From 8fe02e167efa8ed4a4503a5eedc0f49fcb7e3eb9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 21 Oct 2013 19:22:25 +0200 Subject: cfg80211: consolidate passive-scan and no-ibss flags These two flags are used for the same purpose, just combine them into a no-ir flag to annotate no initiating radiation is allowed. Old userspace sending either flag will have it treated as the no-ir flag. To be considerate to older userspace we also send both the no-ir flag and the old no-ibss flags. Newer userspace will have to be aware of older kernels. Update all places in the tree using these flags with the following semantic patch: @@ @@ -NL80211_RRF_PASSIVE_SCAN +NL80211_RRF_NO_IR @@ @@ -NL80211_RRF_NO_IBSS +NL80211_RRF_NO_IR @@ @@ -IEEE80211_CHAN_PASSIVE_SCAN +IEEE80211_CHAN_NO_IR @@ @@ -IEEE80211_CHAN_NO_IBSS +IEEE80211_CHAN_NO_IR @@ @@ -NL80211_RRF_NO_IR | NL80211_RRF_NO_IR +NL80211_RRF_NO_IR @@ @@ -IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_IR +IEEE80211_CHAN_NO_IR @@ @@ -(NL80211_RRF_NO_IR) +NL80211_RRF_NO_IR @@ @@ -(IEEE80211_CHAN_NO_IR) +IEEE80211_CHAN_NO_IR Along with some hand-optimisations in documentation, to remove duplicates and to fix some indentation. Signed-off-by: Luis R. Rodriguez [do all the driver updates in one go] Signed-off-by: Johannes Berg --- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index d7a9745..fd0a497 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -812,7 +812,7 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg, struct ieee80211_channel *chan = request->channels[i]; if (chan->flags & (IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_PASSIVE_SCAN)) + IEEE80211_CHAN_NO_IR)) continue; chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 571f013..b6a09f9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -202,9 +202,9 @@ static struct ieee80211_supported_band __wl_band_5ghz_a = { /* This is to override regulatory domains defined in cfg80211 module (reg.c) * By default world regulatory domain defined in reg.c puts the flags - * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for - * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't - * start p2p operations on 5GHz channels. All the changes in world regulatory + * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165). + * With respect to these flags, wpa_supplicant doesn't * start p2p + * operations on 5GHz channels. All the changes in world regulatory * domain are to be done here. */ static const struct ieee80211_regdomain brcmf_regdom = { @@ -5197,10 +5197,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) if (channel & WL_CHAN_RADAR) band_chan_arr[index].flags |= (IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_NO_IBSS); + IEEE80211_CHAN_NO_IR); if (channel & WL_CHAN_PASSIVE) band_chan_arr[index].flags |= - IEEE80211_CHAN_PASSIVE_SCAN; + IEEE80211_CHAN_NO_IR; } } if (!update) -- cgit v1.1 From a2f73b6c5db3c272d87eaebb5bed355d75a0f25f Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 11 Nov 2013 22:15:29 +0100 Subject: cfg80211: move regulatory flags to their own variable We'll expand this later, this will make it easier to classify and review what things are related to regulatory or not. Coccinelle only missed 4 hits, which I had to do manually, supplying the SmPL in case of merge conflicts. @@ struct wiphy *wiphy; @@ -wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY +wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG @@ expression e; @@ -e->flags |= WIPHY_FLAG_CUSTOM_REGULATORY +e->regulatory_flags |= REGULATORY_CUSTOM_REG @@ struct wiphy *wiphy; @@ -wiphy->flags &= ~WIPHY_FLAG_CUSTOM_REGULATORY +wiphy->regulatory_flags &= ~REGULATORY_CUSTOM_REG @@ struct wiphy *wiphy; @@ -wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY +wiphy->regulatory_flags & REGULATORY_CUSTOM_REG @@ struct wiphy *wiphy; @@ -wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY +wiphy->regulatory_flags |= REGULATORY_STRICT_REG @@ expression e; @@ -e->flags |= WIPHY_FLAG_STRICT_REGULATORY +e->regulatory_flags |= REGULATORY_STRICT_REG @@ struct wiphy *wiphy; @@ -wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY +wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG @@ struct wiphy *wiphy; @@ -wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY +wiphy->regulatory_flags & REGULATORY_STRICT_REG @@ struct wiphy *wiphy; @@ -wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS +wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS @@ expression e; @@ -e->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS +e->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS @@ struct wiphy *wiphy; @@ -wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS +wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS @@ struct wiphy *wiphy; @@ -wiphy->flags & WIPHY_FLAG_DISABLE_BEACON_HINTS +wiphy->regulatory_flags & REGULATORY_DISABLE_BEACON_HINTS Generated-by: Coccinelle SmPL Cc: Julia Lawall Cc: Peter Senna Tschudin Cc: Mihir Shete Cc: Henri Bahini Cc: Tushnim Bhattacharyya Signed-off-by: Luis R. Rodriguez [fix up whitespace damage, overly long lines] Signed-off-by: Johannes Berg --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index b6a09f9..1850efa 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4341,7 +4341,7 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev) wiphy->max_remain_on_channel_duration = 5000; brcmf_wiphy_pno_params(wiphy); brcmf_dbg(INFO, "Registering custom regulatory\n"); - wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY; + wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG; wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom); err = wiphy_register(wiphy); if (err < 0) { -- cgit v1.1 From b176e629402f41f2b984d3aa842ddae23ed5562e Mon Sep 17 00:00:00 2001 From: Andrei Otcheretianski Date: Mon, 18 Nov 2013 19:06:49 +0200 Subject: cfg80211: aggregate mgmt_tx parameters into a struct Change cfg80211 and mac80211 to use cfg80211_mgmt_tx_params struct to aggregate parameters for mgmt_tx functions. This makes the functions' signatures less clumsy and allows less painful parameters extension. Signed-off-by: Andrei Otcheretianski [fix all other drivers] Signed-off-by: Johannes Berg --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 1850efa..f0bdfb1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -3973,11 +3973,12 @@ brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy, static int brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, - struct ieee80211_channel *chan, bool offchan, - unsigned int wait, const u8 *buf, size_t len, - bool no_cck, bool dont_wait_for_ack, u64 *cookie) + struct cfg80211_mgmt_tx_params *params, u64 *cookie) { struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct ieee80211_channel *chan = params->chan; + const u8 *buf = params->buf; + size_t len = params->len; const struct ieee80211_mgmt *mgmt; struct brcmf_cfg80211_vif *vif; s32 err = 0; -- cgit v1.1 From 1e86d69662d7d86360624f74bbe1b5fa1b8ffb13 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Fri, 29 Nov 2013 11:48:13 +0100 Subject: brcmfmac: Update fwsignal to fix out of order tx. When using fwsignal it is possible that tx packets get delivered out of order. This patch fixes that by reordering suppressed packets and tracking generation bit and sequence number per packet. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 167 ++++++++++++++++++--- 1 file changed, 146 insertions(+), 21 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index d0cd0bf..784cf94 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -105,6 +105,9 @@ static struct { }; #undef BRCMF_FWS_TLV_DEF +#define BRCMF_FWS_TYPE_SEQ_LEN 2 + + static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) { int i; @@ -147,8 +150,15 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 -#define BRCMF_FWS_RET_OK_NOSCHEDULE 0 -#define BRCMF_FWS_RET_OK_SCHEDULE 1 +#define BRCMF_FWS_RET_OK_NOSCHEDULE 0 +#define BRCMF_FWS_RET_OK_SCHEDULE 1 + +#define BRCMF_FWS_MODE_REUSESEQ_SHIFT 3 /* seq reuse */ +#define BRCMF_FWS_MODE_SET_REUSESEQ(x, val) ((x) = \ + ((x) & ~(1 << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) | \ + (((val) & 1) << BRCMF_FWS_MODE_REUSESEQ_SHIFT)) +#define BRCMF_FWS_MODE_GET_REUSESEQ(x) \ + (((x) >> BRCMF_FWS_MODE_REUSESEQ_SHIFT) & 1) /** * enum brcmf_fws_skb_state - indicates processing state of skb. @@ -171,6 +181,7 @@ enum brcmf_fws_skb_state { * @bus_flags: 2 bytes reserved for bus specific parameters * @if_flags: holds interface index and packet related flags. * @htod: host to device packet identifier (used in PKTTAG tlv). + * @htod_seq: this 16-bit is original seq number for every suppress packet. * @state: transmit state of the packet. * @mac: descriptor related to destination for this packet. * @@ -181,6 +192,7 @@ struct brcmf_skbuff_cb { u16 bus_flags; u16 if_flags; u32 htod; + u16 htod_seq; enum brcmf_fws_skb_state state; struct brcmf_fws_mac_descriptor *mac; }; @@ -257,6 +269,22 @@ struct brcmf_skbuff_cb { BRCMF_SKB_HTOD_TAG_ ## field ## _MASK, \ BRCMF_SKB_HTOD_TAG_ ## field ## _SHIFT) +#define BRCMF_SKB_HTOD_SEQ_FROMFW_MASK 0x2000 +#define BRCMF_SKB_HTOD_SEQ_FROMFW_SHIFT 13 +#define BRCMF_SKB_HTOD_SEQ_FROMDRV_MASK 0x1000 +#define BRCMF_SKB_HTOD_SEQ_FROMDRV_SHIFT 12 +#define BRCMF_SKB_HTOD_SEQ_NR_MASK 0x0fff +#define BRCMF_SKB_HTOD_SEQ_NR_SHIFT 0 + +#define brcmf_skb_htod_seq_set_field(skb, field, value) \ + brcmu_maskset16(&(brcmf_skbcb(skb)->htod_seq), \ + BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \ + BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT, (value)) +#define brcmf_skb_htod_seq_get_field(skb, field) \ + brcmu_maskget16(brcmf_skbcb(skb)->htod_seq, \ + BRCMF_SKB_HTOD_SEQ_ ## field ## _MASK, \ + BRCMF_SKB_HTOD_SEQ_ ## field ## _SHIFT) + #define BRCMF_FWS_TXSTAT_GENERATION_MASK 0x80000000 #define BRCMF_FWS_TXSTAT_GENERATION_SHIFT 31 #define BRCMF_FWS_TXSTAT_FLAGS_MASK 0x78000000 @@ -265,8 +293,8 @@ struct brcmf_skbuff_cb { #define BRCMF_FWS_TXSTAT_FIFO_SHIFT 24 #define BRCMF_FWS_TXSTAT_HSLOT_MASK 0x00FFFF00 #define BRCMF_FWS_TXSTAT_HSLOT_SHIFT 8 -#define BRCMF_FWS_TXSTAT_PKTID_MASK 0x00FFFFFF -#define BRCMF_FWS_TXSTAT_PKTID_SHIFT 0 +#define BRCMF_FWS_TXSTAT_FREERUN_MASK 0x000000FF +#define BRCMF_FWS_TXSTAT_FREERUN_SHIFT 0 #define brcmf_txstatus_get_field(txs, field) \ brcmu_maskget32(txs, BRCMF_FWS_TXSTAT_ ## field ## _MASK, \ @@ -443,6 +471,7 @@ struct brcmf_fws_info { unsigned long borrow_defer_timestamp; bool bus_flow_blocked; bool creditmap_received; + u8 mode; }; /* @@ -812,13 +841,16 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) u16 data_offset = 0; u8 fillers; __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); + __le16 pktseq = cpu_to_le16(brcmf_skbcb(skb)->htod_seq); - brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n", + brcmf_dbg(TRACE, "enter: %s, idx=%d hslot=%d htod %X seq %X\n", entry->name, brcmf_skb_if_flags_get_field(skb, INDEX), - le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); + (le32_to_cpu(pkttag) >> 8) & 0xffff, + brcmf_skbcb(skb)->htod, brcmf_skbcb(skb)->htod_seq); if (entry->send_tim_signal) data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; - + if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) + data_offset += BRCMF_FWS_TYPE_SEQ_LEN; /* +2 is for Type[1] and Len[1] in TLV, plus TIM signal */ data_offset += 2 + BRCMF_FWS_TYPE_PKTTAG_LEN; fillers = round_up(data_offset, 4) - data_offset; @@ -830,7 +862,12 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) wlh[0] = BRCMF_FWS_TYPE_PKTTAG; wlh[1] = BRCMF_FWS_TYPE_PKTTAG_LEN; memcpy(&wlh[2], &pkttag, sizeof(pkttag)); - wlh += BRCMF_FWS_TYPE_PKTTAG_LEN + 2; + if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) { + wlh[1] += BRCMF_FWS_TYPE_SEQ_LEN; + memcpy(&wlh[2 + BRCMF_FWS_TYPE_PKTTAG_LEN], &pktseq, + sizeof(pktseq)); + } + wlh += wlh[1] + 2; if (entry->send_tim_signal) { entry->send_tim_signal = 0; @@ -875,6 +912,7 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws, /* create a dummy packet and sent that. The traffic */ /* bitmap info will automatically be attached to that packet */ len = BRCMF_FWS_TYPE_PKTTAG_LEN + 2 + + BRCMF_FWS_TYPE_SEQ_LEN + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2 + 4 + fws->drvr->hdrlen; skb = brcmu_pkt_buf_get_skb(len); @@ -884,6 +922,8 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws, skcb = brcmf_skbcb(skb); skcb->mac = entry; skcb->state = BRCMF_FWS_SKBSTATE_TIM; + skcb->htod = 0; + skcb->htod_seq = 0; bus = fws->drvr->bus_if; err = brcmf_fws_hdrpush(fws, skb); if (err == 0) { @@ -1172,8 +1212,13 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws, { int prec = 2 * fifo; u32 *qfull_stat = &fws->stats.delayq_full_error; - struct brcmf_fws_mac_descriptor *entry; + struct pktq *pq; + struct sk_buff_head *queue; + struct sk_buff *p_head; + struct sk_buff *p_tail; + u32 fr_new; + u32 fr_compare; entry = brcmf_skbcb(p)->mac; if (entry == NULL) { @@ -1185,9 +1230,55 @@ static int brcmf_fws_enq(struct brcmf_fws_info *fws, if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) { prec += 1; qfull_stat = &fws->stats.supprq_full_error; - } - if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) { + /* Fix out of order delivery of frames. Dont assume frame */ + /* can be inserted at the end, but look for correct position */ + pq = &entry->psq; + if (pktq_full(pq) || pktq_pfull(pq, prec)) { + *qfull_stat += 1; + return -ENFILE; + } + queue = &pq->q[prec].skblist; + + p_head = skb_peek(queue); + p_tail = skb_peek_tail(queue); + fr_new = brcmf_skb_htod_tag_get_field(p, FREERUN); + + while (p_head != p_tail) { + fr_compare = brcmf_skb_htod_tag_get_field(p_tail, + FREERUN); + /* be sure to handle wrap of 256 */ + if (((fr_new > fr_compare) && + ((fr_new - fr_compare) < 128)) || + ((fr_new < fr_compare) && + ((fr_compare - fr_new) > 128))) + break; + p_tail = skb_queue_prev(queue, p_tail); + } + /* Position found. Determine what to do */ + if (p_tail == NULL) { + /* empty list */ + __skb_queue_tail(queue, p); + } else { + fr_compare = brcmf_skb_htod_tag_get_field(p_tail, + FREERUN); + if (((fr_new > fr_compare) && + ((fr_new - fr_compare) < 128)) || + ((fr_new < fr_compare) && + ((fr_compare - fr_new) > 128))) { + /* After tail */ + __skb_queue_after(queue, p_tail, p); + } else { + /* Before tail */ + __skb_insert(p, p_tail->prev, p_tail, queue); + } + } + + /* Complete the counters and statistics */ + pq->len++; + if (pq->hi_prec < prec) + pq->hi_prec = (u8) prec; + } else if (brcmu_pktq_penq(&entry->psq, prec, p) == NULL) { *qfull_stat += 1; return -ENFILE; } @@ -1277,7 +1368,8 @@ done: } static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, - struct sk_buff *skb, u32 genbit) + struct sk_buff *skb, u32 genbit, + u16 seq) { struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; u32 hslot; @@ -1298,6 +1390,14 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); if (ret == 0) + brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit); + brcmf_skbcb(skb)->htod_seq = seq; + if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) { + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1); + brcmf_skb_htod_seq_set_field(skb, FROMFW, 0); + } else { + brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0); + } ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb); if (ret != 0) { @@ -1317,7 +1417,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, static int brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, - u32 genbit) + u32 genbit, u16 seq) { u32 fifo; int ret; @@ -1360,8 +1460,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, if (entry->suppressed && entry->suppr_transit_count) entry->suppr_transit_count--; - brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags, - skcb->htod); + brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags, + skcb->htod, seq); /* pick up the implicit credit from this packet */ fifo = brcmf_skb_htod_tag_get_field(skb, FIFO); @@ -1374,7 +1474,8 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, brcmf_fws_macdesc_return_req_credit(skb); if (!remove_from_hanger) - ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit); + ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit, + seq); if (remove_from_hanger || ret) brcmf_txfinalize(fws->drvr, skb, true); @@ -1406,10 +1507,12 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) { __le32 status_le; + __le16 seq_le; u32 status; u32 hslot; u32 genbit; u8 flags; + u16 seq; fws->stats.txs_indicate++; memcpy(&status_le, data, sizeof(status_le)); @@ -1417,9 +1520,16 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) flags = brcmf_txstatus_get_field(status, FLAGS); hslot = brcmf_txstatus_get_field(status, HSLOT); genbit = brcmf_txstatus_get_field(status, GENERATION); + if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) { + memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN], + sizeof(seq_le)); + seq = le16_to_cpu(seq_le); + } else { + seq = 0; + } brcmf_fws_lock(fws); - brcmf_fws_txs_process(fws, flags, hslot, genbit); + brcmf_fws_txs_process(fws, flags, hslot, genbit, seq); brcmf_fws_unlock(fws); return BRCMF_FWS_RET_OK_NOSCHEDULE; } @@ -1610,8 +1720,8 @@ static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, struct brcmf_fws_mac_descriptor *entry = skcb->mac; u8 flags; - brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); - brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); + if (skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED) + brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { /* @@ -1652,7 +1762,7 @@ static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, fws->stats.rollback_failed++; hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, - hslot, 0); + hslot, 0, 0); } else { fws->stats.rollback_success++; brcmf_fws_return_credits(fws, fifo, 1); @@ -1732,6 +1842,8 @@ static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p, struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); int rc, hslot; + skcb->htod = 0; + skcb->htod_seq = 0; hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger); brcmf_skb_htod_tag_set_field(p, HSLOT, hslot); brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]); @@ -1908,6 +2020,7 @@ int brcmf_fws_init(struct brcmf_pub *drvr) struct brcmf_fws_info *fws; u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS; int rc; + u32 mode; drvr->fws = kzalloc(sizeof(*(drvr->fws)), GFP_KERNEL); if (!drvr->fws) { @@ -1966,6 +2079,18 @@ int brcmf_fws_init(struct brcmf_pub *drvr) if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1)) brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n"); + /* Enable seq number reuse, if supported */ + if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) { + if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) { + mode = 0; + BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1); + if (brcmf_fil_iovar_int_set(drvr->iflist[0], + "wlfc_mode", mode) == 0) { + BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1); + } + } + } + brcmf_fws_hanger_init(&fws->hanger); brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0); brcmf_fws_macdesc_set_name(fws, &fws->desc.other); @@ -2022,7 +2147,7 @@ void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb) } brcmf_fws_lock(fws); hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); - brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0); + brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0); brcmf_fws_unlock(fws); } -- cgit v1.1 From 8dee77bab2eda24b48bfb8aecf5ac1370e424416 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 11:48:14 +0100 Subject: brcmfmac: add separate function for passing bus tx overhead The common driver needs the packet overhead for the bus in order to reserve headroom for sk_buffs. For the SDIO driver this depends on firmware features so it is not possible to provide it in the brcmf_attach() call. Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 3 ++- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 14 ++++++++++++-- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 4 +++- drivers/net/wireless/brcm80211/brcmfmac/usb.c | 4 ++-- 4 files changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index a6eb09e..a129d21 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -139,7 +139,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); /* Indication from bus module regarding presence/insertion of dongle. */ -int brcmf_attach(uint bus_hdrlen, struct device *dev); +int brcmf_attach(struct device *dev); /* Indication from bus module regarding removal/absence of dongle */ void brcmf_detach(struct device *dev); /* Indication from bus module that dongle should be reset */ @@ -151,6 +151,7 @@ void brcmf_txflowblock(struct device *dev, bool state); void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); int brcmf_bus_start(struct device *dev); +void brcmf_bus_add_txhdrlen(struct device *dev, uint len); #ifdef CONFIG_BRCMFMAC_SDIO void brcmf_sdio_exit(void); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 64e9cff..0c4c230 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1016,7 +1016,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx) } } -int brcmf_attach(uint bus_hdrlen, struct device *dev) +int brcmf_attach(struct device *dev) { struct brcmf_pub *drvr = NULL; int ret = 0; @@ -1031,7 +1031,7 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) mutex_init(&drvr->proto_block); /* Link to bus module */ - drvr->hdrlen = bus_hdrlen; + drvr->hdrlen = 0; drvr->bus_if = dev_get_drvdata(dev); drvr->bus_if->drvr = drvr; @@ -1138,6 +1138,16 @@ fail: return 0; } +void brcmf_bus_add_txhdrlen(struct device *dev, uint len) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; + + if (drvr) { + drvr->hdrlen += len; + } +} + static void brcmf_bus_detach(struct brcmf_pub *drvr) { brcmf_dbg(TRACE, "Enter\n"); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index b02953c..928983b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3983,7 +3983,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; /* Attach to the common layer, reserve hdr space */ - ret = brcmf_attach(bus->tx_hdrlen, bus->sdiodev->dev); + ret = brcmf_attach(bus->sdiodev->dev); if (ret != 0) { brcmf_err("brcmf_attach failed\n"); goto fail; @@ -4027,6 +4027,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list); } + brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen); + /* if firmware path present try to download and bring up bus */ ret = brcmf_bus_start(bus->sdiodev->dev); if (ret != 0) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 422f44c..51c4de0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -1255,7 +1255,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) bus->chiprev = bus_pub->chiprev; /* Attach to the common driver interface */ - ret = brcmf_attach(0, dev); + ret = brcmf_attach(dev); if (ret) { brcmf_err("brcmf_attach failed\n"); goto fail; @@ -1454,7 +1454,7 @@ static int brcmf_usb_resume(struct usb_interface *intf) struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); brcmf_dbg(USB, "Enter\n"); - if (!brcmf_attach(0, devinfo->dev)) + if (!brcmf_attach(devinfo->dev)) return brcmf_bus_start(&usb->dev); return 0; -- cgit v1.1 From cf4582875a77c13adf8fec79b8ab3896d2b38e97 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 11:48:15 +0100 Subject: brcmfmac: replace dongle command list with .preinit() callback The bus-specific interface allowed a list of dongle commands to be provided to the common driver part. However, upcoming functionality requires a more dynamic behaviour. Hence the list is replaced by a new callback function so the bus-specific driver part can implement this behaviour. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 12 ++++- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 15 +----- .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 10 +++- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 58 +++++++++++----------- 4 files changed, 51 insertions(+), 44 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index a129d21..6a54905 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -34,6 +34,7 @@ struct brcmf_bus_dcmd { /** * struct brcmf_bus_ops - bus callback operations. * + * @preinit: execute bus/device specific dongle init commands (optional). * @init: prepare for communication with dongle. * @stop: clear pending frames, disable data flow. * @txdata: send a data frame to the dongle. When the data @@ -51,6 +52,7 @@ struct brcmf_bus_dcmd { * indicated otherwise these callbacks are mandatory. */ struct brcmf_bus_ops { + int (*preinit)(struct device *dev); int (*init)(struct device *dev); void (*stop)(struct device *dev); int (*txdata)(struct device *dev, struct sk_buff *skb); @@ -85,7 +87,6 @@ struct brcmf_bus { unsigned long tx_realloc; u32 chip; u32 chiprev; - struct list_head dcmd_list; struct brcmf_bus_ops *ops; }; @@ -93,6 +94,13 @@ struct brcmf_bus { /* * callback wrappers */ +static inline int brcmf_bus_preinit(struct brcmf_bus *bus) +{ + if (!bus->ops->preinit) + return 0; + return bus->ops->preinit(bus->dev); +} + static inline int brcmf_bus_init(struct brcmf_bus *bus) { return bus->ops->init(bus->dev); @@ -151,6 +159,8 @@ void brcmf_txflowblock(struct device *dev, bool state); void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); int brcmf_bus_start(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 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 9431af2..5c0c919 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -257,8 +257,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) u8 buf[BRCMF_DCMD_SMLEN]; char *ptr; s32 err; - struct brcmf_bus_dcmd *cmdlst; - struct list_head *cur, *q; /* retreive mac address */ err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr, @@ -342,17 +340,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) brcmf_c_pktfilter_offload_enable(ifp, BRCMF_DEFAULT_PACKET_FILTER, 0, true); - /* set bus specific command if there is any */ - list_for_each_safe(cur, q, &ifp->drvr->bus_if->dcmd_list) { - cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list); - if (cmdlst->name && cmdlst->param && cmdlst->param_len) { - brcmf_fil_iovar_data_set(ifp, cmdlst->name, - cmdlst->param, - cmdlst->param_len); - } - list_del(cur); - kfree(cmdlst); - } + /* do bus specific preinit here */ + err = brcmf_bus_preinit(ifp->drvr->bus_if); done: return err; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 0c4c230..ab207e2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1048,8 +1048,6 @@ int brcmf_attach(struct device *dev) /* attach firmware event handler */ brcmf_fweh_attach(drvr); - INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); - return ret; fail: @@ -1206,6 +1204,14 @@ void brcmf_detach(struct device *dev) kfree(drvr); } +s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_if *ifp = bus_if->drvr->iflist[0]; + + return brcmf_fil_iovar_data_set(ifp, name, data, len); +} + static int brcmf_get_pend_8021x_cnt(struct brcmf_if *ifp) { return atomic_read(&ifp->pend_8021x_cnt); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 928983b..2597a53 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3425,6 +3425,35 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) return ret; } +static int brcmf_sdbrcm_bus_preinit(struct device *dev) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio *bus = sdiodev->bus; + u32 value; + u8 idx; + int err; + + /* sdio bus core specific dcmd */ + idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); + if (bus->ci->c_inf[idx].rev < 12) { + /* for sdio core rev < 12, disable txgloming */ + value = 0; + err = brcmf_iovar_data_set(dev, "bus:txglom", &value, + sizeof(u32)); + } else { + /* otherwise, set txglomalign */ + value = 4; + if (sdiodev->pdata) + value = sdiodev->pdata->sd_sgentry_align; + /* SDIO ADMA requires at least 32 bit alignment */ + value = max_t(u32, value, 4); + err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, + sizeof(u32)); + } + return err; +} + static int brcmf_sdbrcm_bus_init(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); @@ -3905,6 +3934,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) static struct brcmf_bus_ops brcmf_sdio_bus_ops = { .stop = brcmf_sdbrcm_bus_stop, + .preinit = brcmf_sdbrcm_bus_preinit, .init = brcmf_sdbrcm_bus_init, .txdata = brcmf_sdbrcm_bus_txdata, .txctl = brcmf_sdbrcm_bus_txctl, @@ -3916,10 +3946,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_sdio *bus; - struct brcmf_bus_dcmd *dlst; - u32 dngl_txglom; - u32 txglomalign = 0; - u8 idx; brcmf_dbg(TRACE, "Enter\n"); @@ -4003,30 +4029,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) brcmf_sdio_debugfs_create(bus); brcmf_dbg(INFO, "completed!!\n"); - /* sdio bus core specific dcmd */ - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); - dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL); - if (dlst) { - if (bus->ci->c_inf[idx].rev < 12) { - /* for sdio core rev < 12, disable txgloming */ - dngl_txglom = 0; - dlst->name = "bus:txglom"; - dlst->param = (char *)&dngl_txglom; - dlst->param_len = sizeof(u32); - } else { - /* otherwise, set txglomalign */ - if (sdiodev->pdata) - txglomalign = sdiodev->pdata->sd_sgentry_align; - /* SDIO ADMA requires at least 32 bit alignment */ - if (txglomalign < 4) - txglomalign = 4; - dlst->name = "bus:txglomalign"; - dlst->param = (char *)&txglomalign; - dlst->param_len = sizeof(u32); - } - list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list); - } - brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen); /* if firmware path present try to download and bring up bus */ -- cgit v1.1 From dcede4b8767dc4b12ce6324ac772776ae9f28569 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 11:48:16 +0100 Subject: brcmfmac: start netif queues only when setup is completed successful Moving the call to netif_start_queue() after brcmf_cfg80211_up() is completed successful. If not return -EIO instead of -1 as that results in 'Operation not permitted' which can put user on wrong track. Reviewed-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index ab207e2..f4eeaa1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -769,7 +769,6 @@ static int brcmf_netdev_open(struct net_device *ndev) struct brcmf_pub *drvr = ifp->drvr; struct brcmf_bus *bus_if = drvr->bus_if; u32 toe_ol; - s32 ret = 0; brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); @@ -788,14 +787,14 @@ static int brcmf_netdev_open(struct net_device *ndev) else ndev->features &= ~NETIF_F_IP_CSUM; - /* Allow transmit calls */ - netif_start_queue(ndev); if (brcmf_cfg80211_up(ndev)) { brcmf_err("failed to bring up cfg80211\n"); - return -1; + return -EIO; } - return ret; + /* Allow transmit calls */ + netif_start_queue(ndev); + return 0; } static const struct net_device_ops brcmf_netdev_ops_pri = { -- cgit v1.1 From 15265f95c2020940350b2febbc513cbbeae0f77e Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Fri, 29 Nov 2013 11:48:17 +0100 Subject: brcmfmac: remove empty brcmf_proto_stop remove empty brcmf_proto_stop from protocol layer Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Arend Van Spriel Reviewed-by: Hante Meuleman Signed-off-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 5 ----- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 3 --- drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h | 3 --- 3 files changed, 11 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index dd85401..42aaf10 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -385,8 +385,3 @@ void brcmf_proto_detach(struct brcmf_pub *drvr) kfree(drvr->prot); drvr->prot = NULL; } - -void brcmf_proto_stop(struct brcmf_pub *drvr) -{ - /* Nothing to do for CDC */ -} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index f4eeaa1..c34ca70 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1150,9 +1150,6 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr) brcmf_dbg(TRACE, "Enter\n"); if (drvr) { - /* Stop the protocol module */ - brcmf_proto_stop(drvr); - /* Stop the bus module */ brcmf_bus_stop(drvr->bus_if); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 53c6e71..d633362 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h @@ -27,9 +27,6 @@ int brcmf_proto_attach(struct brcmf_pub *drvr); /* Unlink, frees allocated protocol memory (including brcmf_proto) */ void brcmf_proto_detach(struct brcmf_pub *drvr); -/* Stop protocol: sync w/dongle state. */ -void brcmf_proto_stop(struct brcmf_pub *drvr); - /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. */ -- cgit v1.1 From b317d1d543fbafd768525db6fbc11ca4af9c921b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 11:48:18 +0100 Subject: brcmfmac: reduce logging noise accessing SDIO SleepCSR register The SleepCSR register is accessed to wakeup the device from the host side. Depending on the state of the device this may take multiple attempts. The failed attempt are not real failures so reduce the log level specifically for this register. The calling function will scream when the multiple attempts all failed. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 905704e..009d2a0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -156,10 +156,21 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, } } - if (err_ret) - brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "write" : "read", func, regaddr, *byte, err_ret); - + if (err_ret) { + /* + * SleepCSR register access can fail when + * waking up the device so reduce this noise + * in the logs. + */ + if (regaddr != SBSDIO_FUNC1_SLEEPCSR) + brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "write" : "read", func, regaddr, *byte, + err_ret); + else + brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "write" : "read", func, regaddr, *byte, + err_ret); + } return err_ret; } -- cgit v1.1 From 4b776961a0d2099c684f4c2256896cb64e4fa9e7 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:06 +0100 Subject: brcmfmac: support hardware extension header in trace_brcmf_sdpcm_hdr() The SDPCM header can be traced, but it used a fixed header size. With txglom feature the SDPCM header will have additional 8 bytes of hardware extension header so SDIO core can properly handle the txglom packet. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 4 +-- .../net/wireless/brcm80211/brcmfmac/tracepoint.h | 29 +++++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 2597a53..510ab18 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -1147,7 +1147,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header, u8 rx_seq, fc, tx_seq_max; u32 swheader; - trace_brcmf_sdpcm_hdr(false, header); + trace_brcmf_sdpcm_hdr(SDPCM_RX, header); /* hw header */ len = get_unaligned_le16(header); @@ -1271,7 +1271,7 @@ static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header, SDPCM_DOFFSET_MASK; *(((__le32 *)header) + 1) = cpu_to_le32(sw_header); *(((__le32 *)header) + 2) = 0; - trace_brcmf_sdpcm_hdr(true, header); + trace_brcmf_sdpcm_hdr(SDPCM_TX, header); } static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h index 3c67529..d229cda 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h @@ -110,21 +110,32 @@ TRACE_EVENT(brcmf_bdchdr, TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) ); +#ifndef SDPCM_RX +#define SDPCM_RX 0 +#endif +#ifndef SDPCM_TX +#define SDPCM_TX 1 +#endif +#ifndef SDPCM_GLOM +#define SDPCM_GLOM 2 +#endif + TRACE_EVENT(brcmf_sdpcm_hdr, - TP_PROTO(bool tx, void *data), - TP_ARGS(tx, data), + TP_PROTO(u8 dir, void *data), + TP_ARGS(dir, data), TP_STRUCT__entry( - __field(u8, tx) + __field(u8, dir) __field(u16, len) - __array(u8, hdr, 12) + __dynamic_array(u8, hdr, dir == SDPCM_GLOM ? 20 : 12) ), TP_fast_assign( - memcpy(__entry->hdr, data, 12); - __entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8); - __entry->tx = tx ? 1 : 0; + memcpy(__get_dynamic_array(hdr), data, dir == SDPCM_GLOM ? 20 : 12); + __entry->len = *(u8 *)data | (*((u8 *)data + 1) << 8); + __entry->dir = dir; ), - TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX", - __entry->len, __entry->hdr[4]) + TP_printk("sdpcm: %s len %u, seq %d", + __entry->dir == SDPCM_RX ? "RX" : "TX", + __entry->len, ((u8 *)__get_dynamic_array(hdr))[4]) ); #ifdef CONFIG_BRCM_TRACING -- cgit v1.1 From 2f5f817f1aceca10b9fb7eaf8a07b2a67f8ad15c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:07 +0100 Subject: brcmfmac: determine sd host controller related variable earlier The commit "eb9c174 brcmfmac: determine host controller related variables during probe" was not implemented correctly as the information is already needed in brcmf_sdbrcm_probe(). This patch moves it to brcmf_sdioh_attach() instead. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 009d2a0..225493a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -278,6 +278,9 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) { int err_ret = 0; + struct mmc_host *host; + struct sdio_func *func; + uint max_blocks; brcmf_dbg(SDIO, "\n"); @@ -299,6 +302,20 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) brcmf_sdioh_enablefuncs(sdiodev); + /* + * determine host related variables after brcmf_sdio_probe() + * as func->cur_blksize is properly set and F2 init has been + * completed successfully. + */ + func = sdiodev->func[2]; + host = func->card->host; + sdiodev->sg_support = host->max_segs > 1; + max_blocks = min_t(uint, host->max_blk_count, 511u); + sdiodev->max_request_size = min_t(uint, host->max_req_size, + max_blocks * func->cur_blksize); + sdiodev->max_segment_count = min_t(uint, host->max_segs, + SG_MAX_SINGLE_ALLOC); + sdiodev->max_segment_size = host->max_seg_size; out: sdio_release_host(sdiodev->func[1]); brcmf_dbg(SDIO, "Done\n"); @@ -327,8 +344,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, int err; struct brcmf_sdio_dev *sdiodev; struct brcmf_bus *bus_if; - struct mmc_host *host; - uint max_blocks; brcmf_dbg(SDIO, "Enter\n"); brcmf_dbg(SDIO, "Class=%x\n", func->class); @@ -376,19 +391,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, goto fail; } - /* - * determine host related variables after brcmf_sdio_probe() - * as func->cur_blksize is properly set and F2 init has been - * completed successfully. - */ - host = func->card->host; - sdiodev->sg_support = host->max_segs > 1; - max_blocks = min_t(uint, host->max_blk_count, 511u); - sdiodev->max_request_size = min_t(uint, host->max_req_size, - max_blocks * func->cur_blksize); - sdiodev->max_segment_count = min_t(uint, host->max_segs, - SG_MAX_SINGLE_ALLOC); - sdiodev->max_segment_size = host->max_seg_size; brcmf_dbg(SDIO, "F2 init completed...\n"); return 0; -- cgit v1.1 From 9a9e405f95b8c28a76cc0711a603bac7b71dd6b4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:08 +0100 Subject: brcmfmac: fix driver build issue when CONFIG_BRCMDBG is not set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CONFIG_BRCMDBG is not set we get the following build issue: CC [M] drivers/net/wireless/brcm80211/brcmfmac/fwsignal.o drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c: In function ‘brcmf_fws_hdrpush’: drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c:852:18: error: ‘BRCMF_FWS_TYPE_SEQ_LEN’ undeclared The define BRCMF_FWS_TYPE_SEQ_LEN was introduced by: commit 6918f38e4ed4e0493a90a4331e0033bdfc806e00 Author: Hante Meuleman Date: Wed Oct 23 14:58:51 2013 +0200 brcmfmac: Update fwsignal to fix out of order tx. Unfortunately, it was put in conditional part of the source file under #ifdef DEBUG. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 784cf94..296dbf1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -105,8 +105,6 @@ static struct { }; #undef BRCMF_FWS_TLV_DEF -#define BRCMF_FWS_TYPE_SEQ_LEN 2 - static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) { @@ -126,6 +124,12 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) #endif /* DEBUG */ /* + * The PKTTAG tlv has additional bytes when firmware-signalling + * mode has REUSESEQ flag set. + */ +#define BRCMF_FWS_TYPE_SEQ_LEN 2 + +/* * flags used to enable tlv signalling from firmware. */ #define BRCMF_FWS_FLAGS_RSSI_SIGNALS 0x0001 -- cgit v1.1 From bed89b64bcbc73a078028f04f64bc955a87ec8ad Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Fri, 29 Nov 2013 12:25:09 +0100 Subject: brcmfmac: add firmware and nvram file name for bcm4339 Add firmware/nvram file name for bcm4339 so fmac can actually be functional with the chip. Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 510ab18..f017c92 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -499,6 +499,8 @@ enum brcmf_sdio_frmtype { #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" +#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" +#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME); MODULE_FIRMWARE(BCM43143_NVRAM_NAME); @@ -514,6 +516,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); MODULE_FIRMWARE(BCM4334_NVRAM_NAME); MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); MODULE_FIRMWARE(BCM4335_NVRAM_NAME); +MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); +MODULE_FIRMWARE(BCM4339_NVRAM_NAME); struct brcmf_firmware_names { u32 chipid; @@ -537,7 +541,8 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, - { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) } + { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, + { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) } }; -- cgit v1.1 From 8da9d2c86888257c7874687467e9519405aa87d5 Mon Sep 17 00:00:00 2001 From: Franky Lin Date: Fri, 29 Nov 2013 12:25:10 +0100 Subject: brcmfmac: add host tx glomming support New WiFi full dongle supports receiving chained packets in one command through the SDIO bus. This patch adds the support on the host side to send chained packets. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 327 ++++++++++++++------- 1 file changed, 227 insertions(+), 100 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f017c92..f5d36506 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,8 @@ struct rte_console { #define BRCMF_TXBOUND 20 /* Default for max tx frames in one scheduling */ +#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */ + #define BRCMF_TXMINMAX 1 /* Max tx frames if rx still pending */ #define MEMBLOCK 2048 /* Block size used for downloading @@ -360,6 +363,8 @@ struct brcmf_sdio_hdrinfo { u16 len_left; u16 len_nxtfrm; u8 dat_offset; + bool lastfrm; + u16 tail_pad; }; /* misc chip info needed by some of the routines */ @@ -455,6 +460,8 @@ struct brcmf_sdio { bool sleeping; /* SDIO bus sleeping */ u8 tx_hdrlen; /* sdio bus header length for tx packet */ + bool txglom; /* host tx glomming enable flag */ + struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */ }; /* clkstate */ @@ -479,6 +486,10 @@ static const uint max_roundup = 512; #define ALIGNMENT 4 +static int brcmf_sdio_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE; +module_param_named(txglomsz, brcmf_sdio_txglomsz, int, 0); +MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]"); + enum brcmf_sdio_frmtype { BRCMF_SDIO_FT_NORMAL, BRCMF_SDIO_FT_SUPER, @@ -1102,10 +1113,18 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) * host and WiFi dongle which contains information needed for SDIO core and * firmware * - * It consists of 2 parts: hw header and software header + * It consists of 3 parts: hardware header, hardware extension header and + * software header * hardware header (frame tag) - 4 bytes * Byte 0~1: Frame length * Byte 2~3: Checksum, bit-wise inverse of frame length + * hardware extension header - 8 bytes + * Tx glom mode only, N/A for Rx or normal Tx + * Byte 0~1: Packet length excluding hw frame tag + * Byte 2: Reserved + * Byte 3: Frame flags, bit 0: last frame indication + * Byte 4~5: Reserved + * Byte 6~7: Tail padding length * software header - 8 bytes * Byte 0: Rx/Tx sequence number * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag @@ -1116,6 +1135,7 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) * Byte 6~7: Reserved */ #define SDPCM_HWHDR_LEN 4 +#define SDPCM_HWEXT_LEN 8 #define SDPCM_SWHDR_LEN 8 #define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN) /* software header */ @@ -1265,18 +1285,28 @@ static inline void brcmf_sdio_update_hwhdr(u8 *header, u16 frm_length) static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header, struct brcmf_sdio_hdrinfo *hd_info) { - u32 sw_header; + u32 hdrval; + u8 hdr_offset; brcmf_sdio_update_hwhdr(header, hd_info->len); - - sw_header = bus->tx_seq; - sw_header |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) & - SDPCM_CHANNEL_MASK; - sw_header |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) & - SDPCM_DOFFSET_MASK; - *(((__le32 *)header) + 1) = cpu_to_le32(sw_header); - *(((__le32 *)header) + 2) = 0; - trace_brcmf_sdpcm_hdr(SDPCM_TX, header); + hdr_offset = SDPCM_HWHDR_LEN; + + if (bus->txglom) { + hdrval = (hd_info->len - hdr_offset) | (hd_info->lastfrm << 24); + *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval); + hdrval = (u16)hd_info->tail_pad << 16; + *(((__le32 *)(header + hdr_offset)) + 1) = cpu_to_le32(hdrval); + hdr_offset += SDPCM_HWEXT_LEN; + } + + hdrval = hd_info->seq_num; + hdrval |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) & + SDPCM_CHANNEL_MASK; + hdrval |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) & + SDPCM_DOFFSET_MASK; + *((__le32 *)(header + hdr_offset)) = cpu_to_le32(hdrval); + *(((__le32 *)(header + hdr_offset)) + 1) = 0; + trace_brcmf_sdpcm_hdr(SDPCM_TX + !!(bus->txglom), header); } static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) @@ -1876,6 +1906,34 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) return; } +static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt) +{ + u16 head_align, head_pad; + u8 *dat_buf; + + /* SDIO ADMA requires at least 32 bit alignment */ + head_align = 4; + if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4) + head_align = bus->sdiodev->pdata->sd_head_align; + + dat_buf = (u8 *)(pkt->data); + + /* Check head padding */ + head_pad = ((unsigned long)dat_buf % head_align); + if (head_pad) { + if (skb_headroom(pkt) < head_pad) { + bus->sdiodev->bus_if->tx_realloc++; + head_pad = 0; + if (skb_cow(pkt, head_pad)) + return -ENOMEM; + } + skb_push(pkt, head_pad); + dat_buf = (u8 *)(pkt->data); + memset(dat_buf, 0, head_pad + bus->tx_hdrlen); + } + return head_pad; +} + /** * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for * bus layer usage. @@ -1885,16 +1943,18 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) /* bit mask of data length chopped from the previous packet */ #define ALIGN_SKB_CHOP_LEN_MASK 0x7fff -static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev, +static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, struct sk_buff_head *pktq, - struct sk_buff *pkt, uint chan) + struct sk_buff *pkt, u16 total_len) { + struct brcmf_sdio_dev *sdiodev; struct sk_buff *pkt_pad; - u16 tail_pad, tail_chop, sg_align; + u16 tail_pad, tail_chop, sg_align, chain_pad; unsigned int blksize; - u8 *dat_buf; - int ntail; + bool lastfrm; + int ntail, ret; + sdiodev = bus->sdiodev; blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; sg_align = 4; if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4) @@ -1903,14 +1963,23 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev, WARN_ON(blksize % sg_align); /* Check tail padding */ - pkt_pad = NULL; + lastfrm = skb_queue_is_last(pktq, pkt); + tail_pad = 0; tail_chop = pkt->len % sg_align; - tail_pad = sg_align - tail_chop; - tail_pad += blksize - (pkt->len + tail_pad) % blksize; + if (tail_chop) + tail_pad = sg_align - tail_chop; + chain_pad = (total_len + tail_pad) % blksize; + if (lastfrm && chain_pad) + tail_pad += blksize - chain_pad; if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { - pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop); + pkt_pad = bus->txglom_sgpad; + if (pkt_pad == NULL) + brcmu_pkt_buf_get_skb(tail_pad + tail_chop); if (pkt_pad == NULL) return -ENOMEM; + ret = brcmf_sdio_txpkt_hdalign(bus, pkt_pad); + if (unlikely(ret < 0)) + return ret; memcpy(pkt_pad->data, pkt->data + pkt->len - tail_chop, tail_chop); @@ -1925,14 +1994,10 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev, return -ENOMEM; if (skb_linearize(pkt)) return -ENOMEM; - dat_buf = (u8 *)(pkt->data); __skb_put(pkt, tail_pad); } - if (pkt_pad) - return pkt->len + tail_chop; - else - return pkt->len - tail_pad; + return tail_pad; } /** @@ -1951,58 +2016,66 @@ static int brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, uint chan) { - u16 head_pad, head_align; + u16 head_pad, total_len; struct sk_buff *pkt_next; - u8 *dat_buf; - int err; + u8 txseq; + int ret; struct brcmf_sdio_hdrinfo hd_info = {0}; - /* SDIO ADMA requires at least 32 bit alignment */ - head_align = 4; - if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4) - head_align = bus->sdiodev->pdata->sd_head_align; + txseq = bus->tx_seq; + total_len = 0; + skb_queue_walk(pktq, pkt_next) { + /* alignment packet inserted in previous + * loop cycle can be skipped as it is + * already properly aligned and does not + * need an sdpcm header. + */ + if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG) + continue; - pkt_next = pktq->next; - dat_buf = (u8 *)(pkt_next->data); + /* align packet data pointer */ + ret = brcmf_sdio_txpkt_hdalign(bus, pkt_next); + if (ret < 0) + return ret; + head_pad = (u16)ret; + if (head_pad) + memset(pkt_next->data, 0, head_pad + bus->tx_hdrlen); - /* Check head padding */ - head_pad = ((unsigned long)dat_buf % head_align); - if (head_pad) { - if (skb_headroom(pkt_next) < head_pad) { - bus->sdiodev->bus_if->tx_realloc++; - head_pad = 0; - if (skb_cow(pkt_next, head_pad)) - return -ENOMEM; - } - skb_push(pkt_next, head_pad); - dat_buf = (u8 *)(pkt_next->data); - memset(dat_buf, 0, head_pad + bus->tx_hdrlen); - } + total_len += pkt_next->len; - if (bus->sdiodev->sg_support && pktq->qlen > 1) { - err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq, - pkt_next, chan); - if (err < 0) - return err; - hd_info.len = (u16)err; - } else { hd_info.len = pkt_next->len; - } - - hd_info.channel = chan; - hd_info.dat_offset = head_pad + bus->tx_hdrlen; - - /* Now fill the header */ - brcmf_sdio_hdpack(bus, dat_buf, &hd_info); - - if (BRCMF_BYTES_ON() && - ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || - (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) - brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, "Tx Frame:\n"); - else if (BRCMF_HDRS_ON()) - brcmf_dbg_hex_dump(true, pkt_next, head_pad + bus->tx_hdrlen, - "Tx Header:\n"); + hd_info.lastfrm = skb_queue_is_last(pktq, pkt_next); + if (bus->txglom && pktq->qlen > 1) { + ret = brcmf_sdio_txpkt_prep_sg(bus, pktq, + pkt_next, total_len); + if (ret < 0) + return ret; + hd_info.tail_pad = (u16)ret; + total_len += (u16)ret; + } + hd_info.channel = chan; + hd_info.dat_offset = head_pad + bus->tx_hdrlen; + hd_info.seq_num = txseq++; + + /* Now fill the header */ + brcmf_sdio_hdpack(bus, pkt_next->data, &hd_info); + + if (BRCMF_BYTES_ON() && + ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || + (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) + brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, + "Tx Frame:\n"); + else if (BRCMF_HDRS_ON()) + brcmf_dbg_hex_dump(true, pkt_next, + head_pad + bus->tx_hdrlen, + "Tx Header:\n"); + } + /* Hardware length tag of the first packet should be total + * length of the chain (including padding) + */ + if (bus->txglom) + brcmf_sdio_update_hwhdr(pktq->next->data, total_len); return 0; } @@ -2020,6 +2093,7 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq) { u8 *hdr; u32 dat_offset; + u16 tail_pad; u32 dummy_flags, chop_len; struct sk_buff *pkt_next, *tmp, *pkt_prev; @@ -2029,42 +2103,42 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq) chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; if (chop_len) { pkt_prev = pkt_next->prev; - memcpy(pkt_prev->data + pkt_prev->len, - pkt_next->data, chop_len); skb_put(pkt_prev, chop_len); } __skb_unlink(pkt_next, pktq); brcmu_pkt_buf_free_skb(pkt_next); } else { - hdr = pkt_next->data + SDPCM_HWHDR_LEN; + hdr = pkt_next->data + bus->tx_hdrlen - SDPCM_SWHDR_LEN; dat_offset = le32_to_cpu(*(__le32 *)hdr); dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT; skb_pull(pkt_next, dat_offset); + if (bus->txglom) { + tail_pad = le16_to_cpu(*(__le16 *)(hdr - 2)); + skb_trim(pkt_next, pkt_next->len - tail_pad); + } } } } /* Writes a HW/SW header into the packet and sends it. */ /* Assumes: (a) header space already there, (b) caller holds lock */ -static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, +static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, uint chan) { int ret; int i; - struct sk_buff_head localq; + struct sk_buff *pkt_next, *tmp; brcmf_dbg(TRACE, "Enter\n"); - __skb_queue_head_init(&localq); - __skb_queue_tail(&localq, pkt); - ret = brcmf_sdio_txpkt_prep(bus, &localq, chan); + ret = brcmf_sdio_txpkt_prep(bus, pktq, chan); if (ret) goto done; sdio_claim_host(bus->sdiodev->func[1]); ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, &localq); + SDIO_FUNC_2, F2SYNC, pktq); bus->sdcnt.f2txdata++; if (ret < 0) { @@ -2088,42 +2162,56 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, if ((hi == 0) && (lo == 0)) break; } - } sdio_release_host(bus->sdiodev->func[1]); - if (ret == 0) - bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP; done: - brcmf_sdio_txpkt_postp(bus, &localq); - __skb_dequeue_tail(&localq); - brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0); + brcmf_sdio_txpkt_postp(bus, pktq); + if (ret == 0) + bus->tx_seq = (bus->tx_seq + pktq->qlen) % SDPCM_SEQ_WRAP; + skb_queue_walk_safe(pktq, pkt_next, tmp) { + __skb_unlink(pkt_next, pktq); + brcmf_txcomplete(bus->sdiodev->dev, pkt_next, ret == 0); + } return ret; } static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) { struct sk_buff *pkt; + struct sk_buff_head pktq; u32 intstatus = 0; - int ret = 0, prec_out; + int ret = 0, prec_out, i; uint cnt = 0; - u8 tx_prec_map; + u8 tx_prec_map, pkt_num; brcmf_dbg(TRACE, "Enter\n"); tx_prec_map = ~bus->flowcontrol; /* Send frames until the limit or some other event */ - for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) { + for (cnt = 0; (cnt < maxframes) && data_ok(bus);) { + pkt_num = 1; + __skb_queue_head_init(&pktq); + if (bus->txglom) + pkt_num = min_t(u8, bus->tx_max - bus->tx_seq, + brcmf_sdio_txglomsz); + pkt_num = min_t(u32, pkt_num, + brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol)); spin_lock_bh(&bus->txqlock); - pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out); - if (pkt == NULL) { - spin_unlock_bh(&bus->txqlock); - break; + for (i = 0; i < pkt_num; i++) { + pkt = brcmu_pktq_mdeq(&bus->txq, tx_prec_map, + &prec_out); + if (pkt == NULL) + break; + __skb_queue_tail(&pktq, pkt); } spin_unlock_bh(&bus->txqlock); + if (i == 0) + break; - ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL); + ret = brcmf_sdbrcm_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL); + cnt += i; /* In poll mode, need to check for other events */ if (!bus->intr && cnt) { @@ -2670,7 +2758,7 @@ static int brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) { u8 *frame; - u16 len; + u16 len, pad; uint retries = 0; u8 doff = 0; int ret = -1; @@ -2697,13 +2785,15 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) doff += bus->tx_hdrlen; /* Round send length to next SDIO block */ + pad = 0; if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - u16 pad = bus->blocksize - (len % bus->blocksize); - if ((pad <= bus->roundup) && (pad < bus->blocksize)) - len += pad; + pad = bus->blocksize - (len % bus->blocksize); + if ((pad > bus->roundup) || (pad >= bus->blocksize)) + pad = 0; } else if (len % BRCMF_SDALIGN) { - len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); + pad = BRCMF_SDALIGN - (len % BRCMF_SDALIGN); } + len += pad; /* Satisfy length-alignment requirements */ if (len & (ALIGNMENT - 1)) @@ -2719,8 +2809,16 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) hd_info.len = (u16)msglen; hd_info.channel = SDPCM_CONTROL_CHANNEL; hd_info.dat_offset = doff; + hd_info.seq_num = bus->tx_seq; + if (bus->txglom) { + hd_info.lastfrm = true; + hd_info.tail_pad = pad; + } brcmf_sdio_hdpack(bus, frame, &hd_info); + if (bus->txglom) + brcmf_sdio_update_hwhdr(frame, len); + if (!data_ok(bus)) { brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", bus->tx_max, bus->tx_seq); @@ -3435,11 +3533,15 @@ static int brcmf_sdbrcm_bus_preinit(struct device *dev) struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; + uint pad_size; u32 value; u8 idx; int err; - /* sdio bus core specific dcmd */ + /* the commands below use the terms tx and rx from + * a device perspective, ie. bus:txglom affects the + * bus transfers from device to host. + */ idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); if (bus->ci->c_inf[idx].rev < 12) { /* for sdio core rev < 12, disable txgloming */ @@ -3456,6 +3558,32 @@ static int brcmf_sdbrcm_bus_preinit(struct device *dev) err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, sizeof(u32)); } + + if (err < 0) + goto done; + + bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; + if (sdiodev->sg_support) { + bus->txglom = false; + value = 1; + pad_size = bus->sdiodev->func[2]->cur_blksize << 1; + bus->txglom_sgpad = brcmu_pkt_buf_get_skb(pad_size); + if (!bus->txglom_sgpad) + brcmf_err("allocating txglom padding skb failed, reduced performance\n"); + + err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom", + &value, sizeof(u32)); + if (err < 0) { + /* bus:rxglom is allowed to fail */ + err = 0; + } else { + bus->txglom = true; + bus->tx_hdrlen += SDPCM_HWEXT_LEN; + } + } + brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen); + +done: return err; } @@ -3929,6 +4057,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) brcmf_sdbrcm_release_dongle(bus); } + brcmu_pkt_buf_free_skb(bus->txglom_sgpad); brcmf_sdbrcm_release_malloc(bus); kfree(bus); @@ -4034,8 +4163,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) brcmf_sdio_debugfs_create(bus); brcmf_dbg(INFO, "completed!!\n"); - brcmf_bus_add_txhdrlen(bus->sdiodev->dev, bus->tx_hdrlen); - /* if firmware path present try to download and bring up bus */ ret = brcmf_bus_start(bus->sdiodev->dev); if (ret != 0) { -- cgit v1.1 From 5d406f8e03921b742fb549def43939254572dee9 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Fri, 29 Nov 2013 12:46:29 +0100 Subject: brcmfmac: rename dhd_cdc to bcdc dhd_cdc is renamed to bcdc. This is a step in cleaning and restructuring protocol layer. This is done so new protocols can be added in the future. This step only renames the source files. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman [arend@broadcom.com: use 'git mv' to do the rename] Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 2 +- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 387 ++++++++++++++++++++++ drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 387 ---------------------- 3 files changed, 388 insertions(+), 388 deletions(-) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcdc.c delete mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 8e9b122..e15b61c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -28,7 +28,7 @@ brcmfmac-objs += \ fweh.o \ fwsignal.o \ p2p.o \ - dhd_cdc.o \ + bcdc.o \ dhd_common.o \ dhd_linux.o \ btcoex.o diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c new file mode 100644 index 0000000..42aaf10 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2010 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/******************************************************************************* + * Communicates with the dongle by using dcmd codes. + * For certain dcmd codes, the dongle interprets string data from the host. + ******************************************************************************/ + +#include +#include + +#include +#include + +#include "dhd.h" +#include "dhd_proto.h" +#include "dhd_bus.h" +#include "fwsignal.h" +#include "dhd_dbg.h" +#include "tracepoint.h" + +struct brcmf_proto_cdc_dcmd { + __le32 cmd; /* dongle command value */ + __le32 len; /* lower 16: output buflen; + * upper 16: input buflen (excludes header) */ + __le32 flags; /* flag defns given below */ + __le32 status; /* status code returned from the device */ +}; + +/* Max valid buffer size that can be sent to the dongle */ +#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) + +/* CDC flag definitions */ +#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */ +#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ +#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */ +#define CDC_DCMD_IF_SHIFT 12 +#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */ +#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */ +#define CDC_DCMD_ID(flags) \ + (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT) + +/* + * BDC header - Broadcom specific extension of CDC. + * Used on data packets to convey priority across USB. + */ +#define BDC_HEADER_LEN 4 +#define BDC_PROTO_VER 2 /* Protocol version */ +#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ +#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ +#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ +#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ +#define BDC_PRIORITY_MASK 0x7 +#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ +#define BDC_FLAG2_IF_SHIFT 0 + +#define BDC_GET_IF_IDX(hdr) \ + ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) +#define BDC_SET_IF_IDX(hdr, idx) \ + ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ + ((idx) << BDC_FLAG2_IF_SHIFT))) + +/** + * struct brcmf_proto_bdc_header - BDC header format + * + * @flags: flags contain protocol and checksum info. + * @priority: 802.1d priority and USB flow control info (bit 4:7). + * @flags2: additional flags containing dongle interface index. + * @data_offset: start of packet data. header is following by firmware signals. + */ +struct brcmf_proto_bdc_header { + u8 flags; + u8 priority; + u8 flags2; + u8 data_offset; +}; + +/* + * maximum length of firmware signal data between + * the BDC header and packet data in the tx path. + */ +#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12 + +#define RETRIES 2 /* # of retries to retrieve matching dcmd response */ +#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE + * (amount of header tha might be added) + * plus any space that might be needed + * for bus alignment padding. + */ +#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for + * round off at the end of buffer + * Currently is SDIO + */ + +struct brcmf_proto { + u16 reqid; + u8 bus_header[BUS_HEADER_LEN]; + struct brcmf_proto_cdc_dcmd msg; + unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; +}; + +static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) +{ + struct brcmf_proto *prot = drvr->prot; + int len = le32_to_cpu(prot->msg.len) + + sizeof(struct brcmf_proto_cdc_dcmd); + + brcmf_dbg(CDC, "Enter\n"); + + /* NOTE : cdc->msg.len holds the desired length of the buffer to be + * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area + * is actually sent to the dongle + */ + if (len > CDC_MAX_MSG_SIZE) + len = CDC_MAX_MSG_SIZE; + + /* Send request */ + return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len); +} + +static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) +{ + int ret; + struct brcmf_proto *prot = drvr->prot; + + brcmf_dbg(CDC, "Enter\n"); + len += sizeof(struct brcmf_proto_cdc_dcmd); + do { + ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg, + len); + if (ret < 0) + break; + } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id); + + return ret; +} + +int +brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len) +{ + struct brcmf_proto *prot = drvr->prot; + struct brcmf_proto_cdc_dcmd *msg = &prot->msg; + void *info; + int ret = 0, retries = 0; + u32 id, flags; + + brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); + + memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); + + msg->cmd = cpu_to_le32(cmd); + msg->len = cpu_to_le32(len); + flags = (++prot->reqid << CDC_DCMD_ID_SHIFT); + flags = (flags & ~CDC_DCMD_IF_MASK) | + (ifidx << CDC_DCMD_IF_SHIFT); + msg->flags = cpu_to_le32(flags); + + if (buf) + memcpy(prot->buf, buf, len); + + ret = brcmf_proto_cdc_msg(drvr); + if (ret < 0) { + brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n", + ret); + goto done; + } + +retry: + /* wait for interrupt and get first fragment */ + ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); + if (ret < 0) + goto done; + + flags = le32_to_cpu(msg->flags); + id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; + + if ((id < prot->reqid) && (++retries < RETRIES)) + goto retry; + if (id != prot->reqid) { + brcmf_err("%s: unexpected request id %d (expected %d)\n", + brcmf_ifname(drvr, ifidx), id, prot->reqid); + ret = -EINVAL; + goto done; + } + + /* Check info buffer */ + info = (void *)&msg[1]; + + /* Copy info buffer */ + if (buf) { + if (ret < (int)len) + len = ret; + memcpy(buf, info, len); + } + + /* Check the ERROR flag */ + if (flags & CDC_DCMD_ERROR) + ret = le32_to_cpu(msg->status); + +done: + return ret; +} + +int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len) +{ + struct brcmf_proto *prot = drvr->prot; + struct brcmf_proto_cdc_dcmd *msg = &prot->msg; + int ret = 0; + u32 flags, id; + + brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); + + memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); + + msg->cmd = cpu_to_le32(cmd); + msg->len = cpu_to_le32(len); + flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET; + flags = (flags & ~CDC_DCMD_IF_MASK) | + (ifidx << CDC_DCMD_IF_SHIFT); + msg->flags = cpu_to_le32(flags); + + if (buf) + memcpy(prot->buf, buf, len); + + ret = brcmf_proto_cdc_msg(drvr); + if (ret < 0) + goto done; + + ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); + if (ret < 0) + goto done; + + flags = le32_to_cpu(msg->flags); + id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; + + if (id != prot->reqid) { + brcmf_err("%s: unexpected request id %d (expected %d)\n", + brcmf_ifname(drvr, ifidx), id, prot->reqid); + ret = -EINVAL; + goto done; + } + + /* Check the ERROR flag */ + if (flags & CDC_DCMD_ERROR) + ret = le32_to_cpu(msg->status); + +done: + return ret; +} + +static bool pkt_sum_needed(struct sk_buff *skb) +{ + return skb->ip_summed == CHECKSUM_PARTIAL; +} + +static void pkt_set_sum_good(struct sk_buff *skb, bool x) +{ + skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); +} + +void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, + struct sk_buff *pktbuf) +{ + struct brcmf_proto_bdc_header *h; + + brcmf_dbg(CDC, "Enter\n"); + + /* Push BDC header used to convey priority for buses that don't */ + skb_push(pktbuf, BDC_HEADER_LEN); + + h = (struct brcmf_proto_bdc_header *)(pktbuf->data); + + h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); + if (pkt_sum_needed(pktbuf)) + h->flags |= BDC_FLAG_SUM_NEEDED; + + h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); + h->flags2 = 0; + h->data_offset = offset; + BDC_SET_IF_IDX(h, ifidx); + trace_brcmf_bdchdr(pktbuf->data); +} + +int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, + struct sk_buff *pktbuf) +{ + struct brcmf_proto_bdc_header *h; + + brcmf_dbg(CDC, "Enter\n"); + + /* Pop BDC header used to convey priority for buses that don't */ + + if (pktbuf->len <= BDC_HEADER_LEN) { + brcmf_dbg(INFO, "rx data too short (%d <= %d)\n", + pktbuf->len, BDC_HEADER_LEN); + return -EBADE; + } + + trace_brcmf_bdchdr(pktbuf->data); + h = (struct brcmf_proto_bdc_header *)(pktbuf->data); + + *ifidx = BDC_GET_IF_IDX(h); + if (*ifidx >= BRCMF_MAX_IFS) { + brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); + return -EBADE; + } + /* The ifidx is the idx to map to matching netdev/ifp. When receiving + * events this is easy because it contains the bssidx which maps + * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. + * bssidx 1 is used for p2p0 and no data can be received or + * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 + */ + if (*ifidx) + (*ifidx)++; + + if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != + BDC_PROTO_VER) { + brcmf_err("%s: non-BDC packet received, flags 0x%x\n", + brcmf_ifname(drvr, *ifidx), h->flags); + return -EBADE; + } + + if (h->flags & BDC_FLAG_SUM_GOOD) { + brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n", + brcmf_ifname(drvr, *ifidx), h->flags); + pkt_set_sum_good(pktbuf, true); + } + + pktbuf->priority = h->priority & BDC_PRIORITY_MASK; + + skb_pull(pktbuf, BDC_HEADER_LEN); + if (do_fws) + brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); + else + skb_pull(pktbuf, h->data_offset << 2); + + if (pktbuf->len == 0) + return -ENODATA; + return 0; +} + +int brcmf_proto_attach(struct brcmf_pub *drvr) +{ + struct brcmf_proto *cdc; + + cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC); + if (!cdc) + goto fail; + + /* ensure that the msg buf directly follows the cdc msg struct */ + if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) { + brcmf_err("struct brcmf_proto is not correctly defined\n"); + goto fail; + } + + drvr->prot = cdc; + drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; + drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + + sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; + return 0; + +fail: + kfree(cdc); + return -ENOMEM; +} + +/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ +void brcmf_proto_detach(struct brcmf_pub *drvr) +{ + kfree(drvr->prot); + drvr->prot = NULL; +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c deleted file mode 100644 index 42aaf10..0000000 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/******************************************************************************* - * Communicates with the dongle by using dcmd codes. - * For certain dcmd codes, the dongle interprets string data from the host. - ******************************************************************************/ - -#include -#include - -#include -#include - -#include "dhd.h" -#include "dhd_proto.h" -#include "dhd_bus.h" -#include "fwsignal.h" -#include "dhd_dbg.h" -#include "tracepoint.h" - -struct brcmf_proto_cdc_dcmd { - __le32 cmd; /* dongle command value */ - __le32 len; /* lower 16: output buflen; - * upper 16: input buflen (excludes header) */ - __le32 flags; /* flag defns given below */ - __le32 status; /* status code returned from the device */ -}; - -/* Max valid buffer size that can be sent to the dongle */ -#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) - -/* CDC flag definitions */ -#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */ -#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ -#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */ -#define CDC_DCMD_IF_SHIFT 12 -#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */ -#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */ -#define CDC_DCMD_ID(flags) \ - (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT) - -/* - * BDC header - Broadcom specific extension of CDC. - * Used on data packets to convey priority across USB. - */ -#define BDC_HEADER_LEN 4 -#define BDC_PROTO_VER 2 /* Protocol version */ -#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ -#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ -#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ -#define BDC_PRIORITY_MASK 0x7 -#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ -#define BDC_FLAG2_IF_SHIFT 0 - -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ - ((idx) << BDC_FLAG2_IF_SHIFT))) - -/** - * struct brcmf_proto_bdc_header - BDC header format - * - * @flags: flags contain protocol and checksum info. - * @priority: 802.1d priority and USB flow control info (bit 4:7). - * @flags2: additional flags containing dongle interface index. - * @data_offset: start of packet data. header is following by firmware signals. - */ -struct brcmf_proto_bdc_header { - u8 flags; - u8 priority; - u8 flags2; - u8 data_offset; -}; - -/* - * maximum length of firmware signal data between - * the BDC header and packet data in the tx path. - */ -#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12 - -#define RETRIES 2 /* # of retries to retrieve matching dcmd response */ -#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE - * (amount of header tha might be added) - * plus any space that might be needed - * for bus alignment padding. - */ -#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for - * round off at the end of buffer - * Currently is SDIO - */ - -struct brcmf_proto { - u16 reqid; - u8 bus_header[BUS_HEADER_LEN]; - struct brcmf_proto_cdc_dcmd msg; - unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; -}; - -static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) -{ - struct brcmf_proto *prot = drvr->prot; - int len = le32_to_cpu(prot->msg.len) + - sizeof(struct brcmf_proto_cdc_dcmd); - - brcmf_dbg(CDC, "Enter\n"); - - /* NOTE : cdc->msg.len holds the desired length of the buffer to be - * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area - * is actually sent to the dongle - */ - if (len > CDC_MAX_MSG_SIZE) - len = CDC_MAX_MSG_SIZE; - - /* Send request */ - return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len); -} - -static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) -{ - int ret; - struct brcmf_proto *prot = drvr->prot; - - brcmf_dbg(CDC, "Enter\n"); - len += sizeof(struct brcmf_proto_cdc_dcmd); - do { - ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg, - len); - if (ret < 0) - break; - } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id); - - return ret; -} - -int -brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len) -{ - struct brcmf_proto *prot = drvr->prot; - struct brcmf_proto_cdc_dcmd *msg = &prot->msg; - void *info; - int ret = 0, retries = 0; - u32 id, flags; - - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); - - memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); - - msg->cmd = cpu_to_le32(cmd); - msg->len = cpu_to_le32(len); - flags = (++prot->reqid << CDC_DCMD_ID_SHIFT); - flags = (flags & ~CDC_DCMD_IF_MASK) | - (ifidx << CDC_DCMD_IF_SHIFT); - msg->flags = cpu_to_le32(flags); - - if (buf) - memcpy(prot->buf, buf, len); - - ret = brcmf_proto_cdc_msg(drvr); - if (ret < 0) { - brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n", - ret); - goto done; - } - -retry: - /* wait for interrupt and get first fragment */ - ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); - if (ret < 0) - goto done; - - flags = le32_to_cpu(msg->flags); - id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; - - if ((id < prot->reqid) && (++retries < RETRIES)) - goto retry; - if (id != prot->reqid) { - brcmf_err("%s: unexpected request id %d (expected %d)\n", - brcmf_ifname(drvr, ifidx), id, prot->reqid); - ret = -EINVAL; - goto done; - } - - /* Check info buffer */ - info = (void *)&msg[1]; - - /* Copy info buffer */ - if (buf) { - if (ret < (int)len) - len = ret; - memcpy(buf, info, len); - } - - /* Check the ERROR flag */ - if (flags & CDC_DCMD_ERROR) - ret = le32_to_cpu(msg->status); - -done: - return ret; -} - -int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len) -{ - struct brcmf_proto *prot = drvr->prot; - struct brcmf_proto_cdc_dcmd *msg = &prot->msg; - int ret = 0; - u32 flags, id; - - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); - - memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); - - msg->cmd = cpu_to_le32(cmd); - msg->len = cpu_to_le32(len); - flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET; - flags = (flags & ~CDC_DCMD_IF_MASK) | - (ifidx << CDC_DCMD_IF_SHIFT); - msg->flags = cpu_to_le32(flags); - - if (buf) - memcpy(prot->buf, buf, len); - - ret = brcmf_proto_cdc_msg(drvr); - if (ret < 0) - goto done; - - ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); - if (ret < 0) - goto done; - - flags = le32_to_cpu(msg->flags); - id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; - - if (id != prot->reqid) { - brcmf_err("%s: unexpected request id %d (expected %d)\n", - brcmf_ifname(drvr, ifidx), id, prot->reqid); - ret = -EINVAL; - goto done; - } - - /* Check the ERROR flag */ - if (flags & CDC_DCMD_ERROR) - ret = le32_to_cpu(msg->status); - -done: - return ret; -} - -static bool pkt_sum_needed(struct sk_buff *skb) -{ - return skb->ip_summed == CHECKSUM_PARTIAL; -} - -static void pkt_set_sum_good(struct sk_buff *skb, bool x) -{ - skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); -} - -void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, - struct sk_buff *pktbuf) -{ - struct brcmf_proto_bdc_header *h; - - brcmf_dbg(CDC, "Enter\n"); - - /* Push BDC header used to convey priority for buses that don't */ - skb_push(pktbuf, BDC_HEADER_LEN); - - h = (struct brcmf_proto_bdc_header *)(pktbuf->data); - - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (pkt_sum_needed(pktbuf)) - h->flags |= BDC_FLAG_SUM_NEEDED; - - h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); - h->flags2 = 0; - h->data_offset = offset; - BDC_SET_IF_IDX(h, ifidx); - trace_brcmf_bdchdr(pktbuf->data); -} - -int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, - struct sk_buff *pktbuf) -{ - struct brcmf_proto_bdc_header *h; - - brcmf_dbg(CDC, "Enter\n"); - - /* Pop BDC header used to convey priority for buses that don't */ - - if (pktbuf->len <= BDC_HEADER_LEN) { - brcmf_dbg(INFO, "rx data too short (%d <= %d)\n", - pktbuf->len, BDC_HEADER_LEN); - return -EBADE; - } - - trace_brcmf_bdchdr(pktbuf->data); - h = (struct brcmf_proto_bdc_header *)(pktbuf->data); - - *ifidx = BDC_GET_IF_IDX(h); - if (*ifidx >= BRCMF_MAX_IFS) { - brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); - return -EBADE; - } - /* The ifidx is the idx to map to matching netdev/ifp. When receiving - * events this is easy because it contains the bssidx which maps - * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd. - * bssidx 1 is used for p2p0 and no data can be received or - * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0 - */ - if (*ifidx) - (*ifidx)++; - - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != - BDC_PROTO_VER) { - brcmf_err("%s: non-BDC packet received, flags 0x%x\n", - brcmf_ifname(drvr, *ifidx), h->flags); - return -EBADE; - } - - if (h->flags & BDC_FLAG_SUM_GOOD) { - brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n", - brcmf_ifname(drvr, *ifidx), h->flags); - pkt_set_sum_good(pktbuf, true); - } - - pktbuf->priority = h->priority & BDC_PRIORITY_MASK; - - skb_pull(pktbuf, BDC_HEADER_LEN); - if (do_fws) - brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); - else - skb_pull(pktbuf, h->data_offset << 2); - - if (pktbuf->len == 0) - return -ENODATA; - return 0; -} - -int brcmf_proto_attach(struct brcmf_pub *drvr) -{ - struct brcmf_proto *cdc; - - cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC); - if (!cdc) - goto fail; - - /* ensure that the msg buf directly follows the cdc msg struct */ - if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) { - brcmf_err("struct brcmf_proto is not correctly defined\n"); - goto fail; - } - - drvr->prot = cdc; - drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; - drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + - sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; - return 0; - -fail: - kfree(cdc); - return -ENOMEM; -} - -/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -void brcmf_proto_detach(struct brcmf_pub *drvr) -{ - kfree(drvr->prot); - drvr->prot = NULL; -} -- cgit v1.1 From f931868d498ec4e7a1b8730e7173b5a17d36dd1a Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Fri, 29 Nov 2013 12:25:12 +0100 Subject: brcmfmac: removed dhd_proto.h. dhd_proto.h was cleaned up and prototypes were moved to dhd.h. dhd_proto.h was removed. This is a step in cleaning and restucturing protocol layer. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 1 - drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 15 +++++++++ .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 1 - .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 1 - .../net/wireless/brcm80211/brcmfmac/dhd_proto.h | 39 ---------------------- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 1 - 6 files changed, 15 insertions(+), 43 deletions(-) delete mode 100644 drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index 42aaf10..59c6c05 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -26,7 +26,6 @@ #include #include "dhd.h" -#include "dhd_proto.h" #include "dhd_bus.h" #include "fwsignal.h" #include "dhd_dbg.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 899a2ad..dc2ebef 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -635,6 +635,18 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev); /* Return pointer to interface name */ char *brcmf_ifname(struct brcmf_pub *drvr, int idx); +/* Linkage, sets prot link and updates hdrlen in pub */ +int brcmf_proto_attach(struct brcmf_pub *drvr); + +/* Unlink, frees allocated protocol memory (including brcmf_proto) */ +void brcmf_proto_detach(struct brcmf_pub *drvr); + +/* Add any protocol-specific data header. + * Caller must reserve prot_hdrlen prepend space. + */ +void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, + struct sk_buff *txp); + /* Query dongle */ int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); @@ -655,4 +667,7 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp); void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, bool success); +/* Sets dongle media info (drv_version, mac address). */ +int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); + #endif /* _BRCMF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 5c0c919..6017633 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -21,7 +21,6 @@ #include #include "dhd.h" #include "dhd_bus.h" -#include "dhd_proto.h" #include "dhd_dbg.h" #include "fwil.h" #include "tracepoint.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c34ca70..c626938 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -24,7 +24,6 @@ #include "dhd.h" #include "dhd_bus.h" -#include "dhd_proto.h" #include "dhd_dbg.h" #include "fwil_types.h" #include "p2p.h" diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h deleted file mode 100644 index d633362..0000000 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BRCMF_PROTO_H_ -#define _BRCMF_PROTO_H_ - -/* - * Exported from the brcmf protocol module (brcmf_cdc) - */ - -/* Linkage, sets prot link and updates hdrlen in pub */ -int brcmf_proto_attach(struct brcmf_pub *drvr); - -/* Unlink, frees allocated protocol memory (including brcmf_proto) */ -void brcmf_proto_detach(struct brcmf_pub *drvr); - -/* Add any protocol-specific data header. - * Caller must reserve prot_hdrlen prepend space. - */ -void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, - struct sk_buff *txp); - -/* Sets dongle media info (drv_version, mac address). */ -int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); - -#endif /* _BRCMF_PROTO_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index 296dbf1..b96ee3a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -27,7 +27,6 @@ #include #include #include "dhd.h" -#include "dhd_proto.h" #include "dhd_dbg.h" #include "dhd_bus.h" #include "fwil.h" -- cgit v1.1 From e217d1c8bfbd97316f5a1d3845587284cc137291 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:13 +0100 Subject: brcmfmac: determine alignment values during probe The alignment values were being determined for each transmit and receive depending on platform data. Instead determine these once during the probe. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 48 +++++++++++----------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f5d36506..584ffb8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -462,6 +462,8 @@ struct brcmf_sdio { u8 tx_hdrlen; /* sdio bus header length for tx packet */ bool txglom; /* host tx glomming enable flag */ struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */ + u16 head_align; /* buffer pointer alignment */ + u16 sgentry_align; /* scatter-gather buffer alignment */ }; /* clkstate */ @@ -1313,7 +1315,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) { u16 dlen, totlen; u8 *dptr, num = 0; - u32 align = 0; u16 sublen; struct sk_buff *pfirst, *pnext; @@ -1328,11 +1329,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) brcmf_dbg(SDIO, "start: glomd %p glom %p\n", bus->glomd, skb_peek(&bus->glom)); - if (bus->sdiodev->pdata) - align = bus->sdiodev->pdata->sd_sgentry_align; - if (align < 4) - align = 4; - /* If there's a descriptor, generate the packet chain */ if (bus->glomd) { pfirst = pnext = NULL; @@ -1356,9 +1352,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) pnext = NULL; break; } - if (sublen % align) { + if (sublen % bus->sgentry_align) { brcmf_err("sublen %d not multiple of %d\n", - sublen, align); + sublen, bus->sgentry_align); } totlen += sublen; @@ -1371,7 +1367,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } /* Allocate/chain packet for next subframe */ - pnext = brcmu_pkt_buf_get_skb(sublen + align); + pnext = brcmu_pkt_buf_get_skb(sublen + bus->sgentry_align); if (pnext == NULL) { brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n", num, sublen); @@ -1380,7 +1376,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) skb_queue_tail(&bus->glom, pnext); /* Adhere to start alignment requirements */ - pkt_align(pnext, sublen, align); + pkt_align(pnext, sublen, bus->sgentry_align); } /* If all allocations succeeded, save packet chain @@ -1908,18 +1904,13 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt) { - u16 head_align, head_pad; + u16 head_pad; u8 *dat_buf; - /* SDIO ADMA requires at least 32 bit alignment */ - head_align = 4; - if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4) - head_align = bus->sdiodev->pdata->sd_head_align; - dat_buf = (u8 *)(pkt->data); /* Check head padding */ - head_pad = ((unsigned long)dat_buf % head_align); + head_pad = ((unsigned long)dat_buf % bus->head_align); if (head_pad) { if (skb_headroom(pkt) < head_pad) { bus->sdiodev->bus_if->tx_realloc++; @@ -1949,25 +1940,22 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus, { struct brcmf_sdio_dev *sdiodev; struct sk_buff *pkt_pad; - u16 tail_pad, tail_chop, sg_align, chain_pad; + u16 tail_pad, tail_chop, chain_pad; unsigned int blksize; bool lastfrm; int ntail, ret; sdiodev = bus->sdiodev; blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; - sg_align = 4; - if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4) - sg_align = sdiodev->pdata->sd_sgentry_align; /* sg entry alignment should be a divisor of block size */ - WARN_ON(blksize % sg_align); + WARN_ON(blksize % bus->sgentry_align); /* Check tail padding */ lastfrm = skb_queue_is_last(pktq, pkt); tail_pad = 0; - tail_chop = pkt->len % sg_align; + tail_chop = pkt->len % bus->sgentry_align; if (tail_chop) - tail_pad = sg_align - tail_chop; + tail_pad = bus->sgentry_align - tail_chop; chain_pad = (total_len + tail_pad) % blksize; if (lastfrm && chain_pad) tail_pad += blksize - chain_pad; @@ -4099,6 +4087,18 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->txminmax = BRCMF_TXMINMAX; bus->tx_seq = SDPCM_SEQ_WRAP - 1; + /* platform specific configuration: + * alignments must be at least 4 bytes for ADMA + */ + bus->head_align = ALIGNMENT; + bus->sgentry_align = ALIGNMENT; + if (sdiodev->pdata) { + if (sdiodev->pdata->sd_head_align > ALIGNMENT) + bus->head_align = sdiodev->pdata->sd_head_align; + if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) + bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; + } + INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); if (bus->brcmf_wq == NULL) { -- cgit v1.1 From 9b2d2f2a890847277371d953e2751c4224efa273 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:14 +0100 Subject: brcmfmac: use platform specific alignment in SDIO The SDIO part of the brcmfmac driver uses a static define BRCMF_SDALIGN to align buffers used for SDIO transfers. This patch replaces it by using alignment derived from the platform specific data. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 50 ++++++++++------------ 1 file changed, 22 insertions(+), 28 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 584ffb8..0f95f3e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -389,7 +389,7 @@ struct brcmf_sdio { u8 tx_seq; /* Transmit sequence number (next) */ u8 tx_max; /* Maximum transmit sequence allowed */ - u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; + u8 *hdrbuf; /* buffer for handling rx frame */ u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ u8 rx_seq; /* Receive sequence number (expected) */ struct brcmf_sdio_hdrinfo cur_read; @@ -1580,9 +1580,9 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) goto done; rbuf = bus->rxbuf; - pad = ((unsigned long)rbuf % BRCMF_SDALIGN); + pad = ((unsigned long)rbuf % bus->head_align); if (pad) - rbuf += (BRCMF_SDALIGN - pad); + rbuf += (bus->head_align - pad); /* Copy the already-read portion over */ memcpy(buf, hdr, BRCMF_FIRSTREAD); @@ -1596,14 +1596,10 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) if ((pad <= bus->roundup) && (pad < bus->blocksize) && ((len + pad) < bus->sdiodev->bus_if->maxctl)) rdlen += pad; - } else if (rdlen % BRCMF_SDALIGN) { - rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); + } else if (rdlen % bus->head_align) { + rdlen += bus->head_align - (rdlen % bus->head_align); } - /* Satisfy length-alignment requirements */ - if (rdlen & (ALIGNMENT - 1)) - rdlen = roundup(rdlen, ALIGNMENT); - /* Drop if the read is too big or it exceeds our maximum */ if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { brcmf_err("%d-byte control read exceeds %d-byte buffer\n", @@ -1668,8 +1664,8 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) if (*pad <= bus->roundup && *pad < bus->blocksize && *rdlen + *pad + BRCMF_FIRSTREAD < MAX_RX_DATASZ) *rdlen += *pad; - } else if (*rdlen % BRCMF_SDALIGN) { - *rdlen += BRCMF_SDALIGN - (*rdlen % BRCMF_SDALIGN); + } else if (*rdlen % bus->head_align) { + *rdlen += bus->head_align - (*rdlen % bus->head_align); } } @@ -1757,7 +1753,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) brcmf_pad(bus, &pad, &rd->len_left); pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read + - BRCMF_SDALIGN); + bus->head_align); if (!pkt) { /* Give up on data, request rtx of events */ brcmf_err("brcmu_pkt_buf_get_skb failed\n"); @@ -1767,7 +1763,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) continue; } skb_pull(pkt, head_read); - pkt_align(pkt, rd->len_left, BRCMF_SDALIGN); + pkt_align(pkt, rd->len_left, bus->head_align); ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); @@ -2762,14 +2758,14 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) len = (msglen += bus->tx_hdrlen); /* Add alignment padding (optional for ctl frames) */ - doff = ((unsigned long)frame % BRCMF_SDALIGN); + doff = ((unsigned long)frame % bus->head_align); if (doff) { frame -= doff; len += doff; msglen += doff; memset(frame, 0, doff + bus->tx_hdrlen); } - /* precondition: doff < BRCMF_SDALIGN */ + /* precondition: doff < bus->head_align */ doff += bus->tx_hdrlen; /* Round send length to next SDIO block */ @@ -2778,15 +2774,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) pad = bus->blocksize - (len % bus->blocksize); if ((pad > bus->roundup) || (pad >= bus->blocksize)) pad = 0; - } else if (len % BRCMF_SDALIGN) { - pad = BRCMF_SDALIGN - (len % BRCMF_SDALIGN); + } else if (len % bus->head_align) { + pad = bus->head_align - (len % bus->head_align); } len += pad; - /* Satisfy length-alignment requirements */ - if (len & (ALIGNMENT - 1)) - len = roundup(len, ALIGNMENT); - /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ /* Make sure backplane clock is on */ @@ -2798,10 +2790,8 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) hd_info.channel = SDPCM_CONTROL_CHANNEL; hd_info.dat_offset = doff; hd_info.seq_num = bus->tx_seq; - if (bus->txglom) { - hd_info.lastfrm = true; - hd_info.tail_pad = pad; - } + hd_info.lastfrm = true; + hd_info.tail_pad = pad; brcmf_sdio_hdpack(bus, frame, &hd_info); if (bus->txglom) @@ -3823,7 +3813,7 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) if (bus->sdiodev->bus_if->maxctl) { bus->rxblen = roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), - ALIGNMENT) + BRCMF_SDALIGN; + ALIGNMENT) + bus->head_align; bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); if (!(bus->rxbuf)) return false; @@ -3924,9 +3914,13 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); + /* allocate header buffer */ + bus->hdrbuf = kzalloc(MAX_HDR_READ + bus->head_align, GFP_KERNEL); + if (!bus->hdrbuf) + return false; /* Locate an appropriately-aligned portion of hdrbuf */ bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], - BRCMF_SDALIGN); + bus->head_align); /* Set the poll and/or interrupt flags */ bus->intr = true; @@ -4047,7 +4041,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) brcmu_pkt_buf_free_skb(bus->txglom_sgpad); brcmf_sdbrcm_release_malloc(bus); - + kfree(bus->hdrbuf); kfree(bus); } -- cgit v1.1 From e601fb37405af384781284f90125fd4da665a7b3 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:15 +0100 Subject: brcmfmac: remove redundant ioctl handlers The ioctl() entry points were empty except for handling SIOC_ETHTOOL but that has been obsoleted in favor of struct ethtool_ops. Cleaning up removing the ioctl() handlers. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 149 --------------------- 1 file changed, 149 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c626938..9336f6d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -591,28 +591,6 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) return &ifp->stats; } -/* - * Set current toe component enables in toe_ol iovar, - * and set toe global enable iovar - */ -static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol) -{ - s32 err; - - err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol); - if (err < 0) { - brcmf_err("Setting toe_ol failed, %d\n", err); - return err; - } - - err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0)); - if (err < 0) - brcmf_err("Setting toe failed, %d\n", err); - - return err; - -} - static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { @@ -630,124 +608,6 @@ static const struct ethtool_ops brcmf_ethtool_ops = { .get_drvinfo = brcmf_ethtool_get_drvinfo, }; -static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) -{ - struct brcmf_pub *drvr = ifp->drvr; - struct ethtool_drvinfo info; - char drvname[sizeof(info.driver)]; - u32 cmd; - struct ethtool_value edata; - u32 toe_cmpnt, csum_dir; - int ret; - - brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); - - /* all ethtool calls start with a cmd word */ - if (copy_from_user(&cmd, uaddr, sizeof(u32))) - return -EFAULT; - - switch (cmd) { - case ETHTOOL_GDRVINFO: - /* Copy out any request driver name */ - if (copy_from_user(&info, uaddr, sizeof(info))) - return -EFAULT; - strncpy(drvname, info.driver, sizeof(info.driver)); - drvname[sizeof(info.driver) - 1] = '\0'; - - /* clear struct for return */ - memset(&info, 0, sizeof(info)); - info.cmd = cmd; - - /* if requested, identify ourselves */ - if (strcmp(drvname, "?dhd") == 0) { - sprintf(info.driver, "dhd"); - strcpy(info.version, BRCMF_VERSION_STR); - } - /* report dongle driver type */ - else - sprintf(info.driver, "wl"); - - sprintf(info.version, "%lu", drvr->drv_version); - if (copy_to_user(uaddr, &info, sizeof(info))) - return -EFAULT; - brcmf_dbg(TRACE, "given %*s, returning %s\n", - (int)sizeof(drvname), drvname, info.driver); - break; - - /* Get toe offload components from dongle */ - case ETHTOOL_GRXCSUM: - case ETHTOOL_GTXCSUM: - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); - if (ret < 0) - return ret; - - csum_dir = - (cmd == ETHTOOL_GTXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - edata.cmd = cmd; - edata.data = (toe_cmpnt & csum_dir) ? 1 : 0; - - if (copy_to_user(uaddr, &edata, sizeof(edata))) - return -EFAULT; - break; - - /* Set toe offload components in dongle */ - case ETHTOOL_SRXCSUM: - case ETHTOOL_STXCSUM: - if (copy_from_user(&edata, uaddr, sizeof(edata))) - return -EFAULT; - - /* Read the current settings, update and write back */ - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); - if (ret < 0) - return ret; - - csum_dir = - (cmd == ETHTOOL_STXCSUM) ? TOE_TX_CSUM_OL : TOE_RX_CSUM_OL; - - if (edata.data != 0) - toe_cmpnt |= csum_dir; - else - toe_cmpnt &= ~csum_dir; - - ret = brcmf_toe_set(ifp, toe_cmpnt); - if (ret < 0) - return ret; - - /* If setting TX checksum mode, tell Linux the new mode */ - if (cmd == ETHTOOL_STXCSUM) { - if (edata.data) - ifp->ndev->features |= NETIF_F_IP_CSUM; - else - ifp->ndev->features &= ~NETIF_F_IP_CSUM; - } - - break; - - default: - return -EOPNOTSUPP; - } - - return 0; -} - -static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, - int cmd) -{ - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_pub *drvr = ifp->drvr; - - brcmf_dbg(TRACE, "Enter, idx=%d, cmd=0x%04x\n", ifp->bssidx, cmd); - - if (!drvr->iflist[ifp->bssidx]) - return -1; - - if (cmd == SIOCETHTOOL) - return brcmf_ethtool(ifp, ifr->ifr_data); - - return -EOPNOTSUPP; -} - static int brcmf_netdev_stop(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); @@ -800,7 +660,6 @@ static const struct net_device_ops brcmf_netdev_ops_pri = { .ndo_open = brcmf_netdev_open, .ndo_stop = brcmf_netdev_stop, .ndo_get_stats = brcmf_netdev_get_stats, - .ndo_do_ioctl = brcmf_netdev_ioctl_entry, .ndo_start_xmit = brcmf_netdev_start_xmit, .ndo_set_mac_address = brcmf_netdev_set_mac_address, .ndo_set_rx_mode = brcmf_netdev_set_multicast_list @@ -866,13 +725,6 @@ static int brcmf_net_p2p_stop(struct net_device *ndev) return brcmf_cfg80211_down(ndev); } -static int brcmf_net_p2p_do_ioctl(struct net_device *ndev, - struct ifreq *ifr, int cmd) -{ - brcmf_dbg(TRACE, "Enter\n"); - return 0; -} - static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb, struct net_device *ndev) { @@ -885,7 +737,6 @@ static netdev_tx_t brcmf_net_p2p_start_xmit(struct sk_buff *skb, static const struct net_device_ops brcmf_netdev_ops_p2p = { .ndo_open = brcmf_net_p2p_open, .ndo_stop = brcmf_net_p2p_stop, - .ndo_do_ioctl = brcmf_net_p2p_do_ioctl, .ndo_start_xmit = brcmf_net_p2p_start_xmit }; -- cgit v1.1 From 85b8413371225e9bcbbb30cf3caa5889fed5f6a4 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Fri, 29 Nov 2013 12:25:16 +0100 Subject: brcmfmac: Dynamically register a protocol layer. BCDC is the default protocol layer and being called directly. This patch installs the functions for this layer dynamically. This allows new protocols to be added and selected dynamically depending on the hw capabilties. As currently only BCDC is supported this is always the installed protocol. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 1 + drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 93 ++++++++++++---------- drivers/net/wireless/brcm80211/brcmfmac/bcdc.h | 24 ++++++ drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 24 +----- .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 +- drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 7 +- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 1 + drivers/net/wireless/brcm80211/brcmfmac/proto.c | 62 +++++++++++++++ drivers/net/wireless/brcm80211/brcmfmac/proto.h | 57 +++++++++++++ 9 files changed, 202 insertions(+), 71 deletions(-) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcdc.h create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/proto.c create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/proto.h (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index e15b61c..2082402 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -28,6 +28,7 @@ brcmfmac-objs += \ fweh.o \ fwsignal.o \ p2p.o \ + proto.o \ bcdc.o \ dhd_common.o \ dhd_linux.o \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index 59c6c05..b5a2529 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -30,6 +30,8 @@ #include "fwsignal.h" #include "dhd_dbg.h" #include "tracepoint.h" +#include "proto.h" +#include "bcdc.h" struct brcmf_proto_cdc_dcmd { __le32 cmd; /* dongle command value */ @@ -104,7 +106,7 @@ struct brcmf_proto_bdc_header { * Currently is SDIO */ -struct brcmf_proto { +struct brcmf_bcdc { u16 reqid; u8 bus_header[BUS_HEADER_LEN]; struct brcmf_proto_cdc_dcmd msg; @@ -113,8 +115,8 @@ struct brcmf_proto { static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) { - struct brcmf_proto *prot = drvr->prot; - int len = le32_to_cpu(prot->msg.len) + + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; + int len = le32_to_cpu(bcdc->msg.len) + sizeof(struct brcmf_proto_cdc_dcmd); brcmf_dbg(CDC, "Enter\n"); @@ -127,32 +129,32 @@ static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) len = CDC_MAX_MSG_SIZE; /* Send request */ - return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&prot->msg, len); + return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); } static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) { int ret; - struct brcmf_proto *prot = drvr->prot; + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; brcmf_dbg(CDC, "Enter\n"); len += sizeof(struct brcmf_proto_cdc_dcmd); do { - ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&prot->msg, + ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); if (ret < 0) break; - } while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id); + } while (CDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id); return ret; } -int -brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len) +static int +brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len) { - struct brcmf_proto *prot = drvr->prot; - struct brcmf_proto_cdc_dcmd *msg = &prot->msg; + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; + struct brcmf_proto_cdc_dcmd *msg = &bcdc->msg; void *info; int ret = 0, retries = 0; u32 id, flags; @@ -163,13 +165,13 @@ brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, msg->cmd = cpu_to_le32(cmd); msg->len = cpu_to_le32(len); - flags = (++prot->reqid << CDC_DCMD_ID_SHIFT); + flags = (++bcdc->reqid << CDC_DCMD_ID_SHIFT); flags = (flags & ~CDC_DCMD_IF_MASK) | (ifidx << CDC_DCMD_IF_SHIFT); msg->flags = cpu_to_le32(flags); if (buf) - memcpy(prot->buf, buf, len); + memcpy(bcdc->buf, buf, len); ret = brcmf_proto_cdc_msg(drvr); if (ret < 0) { @@ -180,18 +182,18 @@ brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, retry: /* wait for interrupt and get first fragment */ - ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); + ret = brcmf_proto_cdc_cmplt(drvr, bcdc->reqid, len); if (ret < 0) goto done; flags = le32_to_cpu(msg->flags); id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; - if ((id < prot->reqid) && (++retries < RETRIES)) + if ((id < bcdc->reqid) && (++retries < RETRIES)) goto retry; - if (id != prot->reqid) { + if (id != bcdc->reqid) { brcmf_err("%s: unexpected request id %d (expected %d)\n", - brcmf_ifname(drvr, ifidx), id, prot->reqid); + brcmf_ifname(drvr, ifidx), id, bcdc->reqid); ret = -EINVAL; goto done; } @@ -214,11 +216,12 @@ done: return ret; } -int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len) +static int +brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len) { - struct brcmf_proto *prot = drvr->prot; - struct brcmf_proto_cdc_dcmd *msg = &prot->msg; + struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; + struct brcmf_proto_cdc_dcmd *msg = &bcdc->msg; int ret = 0; u32 flags, id; @@ -228,28 +231,28 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, msg->cmd = cpu_to_le32(cmd); msg->len = cpu_to_le32(len); - flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET; + flags = (++bcdc->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET; flags = (flags & ~CDC_DCMD_IF_MASK) | (ifidx << CDC_DCMD_IF_SHIFT); msg->flags = cpu_to_le32(flags); if (buf) - memcpy(prot->buf, buf, len); + memcpy(bcdc->buf, buf, len); ret = brcmf_proto_cdc_msg(drvr); if (ret < 0) goto done; - ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len); + ret = brcmf_proto_cdc_cmplt(drvr, bcdc->reqid, len); if (ret < 0) goto done; flags = le32_to_cpu(msg->flags); id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; - if (id != prot->reqid) { + if (id != bcdc->reqid) { brcmf_err("%s: unexpected request id %d (expected %d)\n", - brcmf_ifname(drvr, ifidx), id, prot->reqid); + brcmf_ifname(drvr, ifidx), id, bcdc->reqid); ret = -EINVAL; goto done; } @@ -272,7 +275,8 @@ static void pkt_set_sum_good(struct sk_buff *skb, bool x) skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); } -void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, +static void +brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, struct sk_buff *pktbuf) { struct brcmf_proto_bdc_header *h; @@ -295,8 +299,9 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, trace_brcmf_bdchdr(pktbuf->data); } -int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, - struct sk_buff *pktbuf) +static int +brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, + struct sk_buff *pktbuf) { struct brcmf_proto_bdc_header *h; @@ -353,34 +358,38 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, return 0; } -int brcmf_proto_attach(struct brcmf_pub *drvr) +int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { - struct brcmf_proto *cdc; + struct brcmf_bcdc *bcdc; - cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC); - if (!cdc) + bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC); + if (!bcdc) goto fail; /* ensure that the msg buf directly follows the cdc msg struct */ - if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) { - brcmf_err("struct brcmf_proto is not correctly defined\n"); + if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) { + brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n"); goto fail; } - drvr->prot = cdc; + drvr->proto->hdrpush = brcmf_proto_bcdc_hdrpush; + drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull; + drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd; + drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd; + drvr->proto->pd = bcdc; + drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; return 0; fail: - kfree(cdc); + kfree(bcdc); return -ENOMEM; } -/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */ -void brcmf_proto_detach(struct brcmf_pub *drvr) +void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) { - kfree(drvr->prot); - drvr->prot = NULL; + kfree(drvr->proto->pd); + drvr->proto->pd = NULL; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h new file mode 100644 index 0000000..17e8c03 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BRCMFMAC_BCDC_H +#define BRCMFMAC_BCDC_H + + +int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); +void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); + + +#endif /* BRCMFMAC_BCDC_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index dc2ebef..4ed7a97 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -535,7 +535,7 @@ struct brcmf_fws_info; /* firmware signalling info */ struct brcmf_pub { /* Linkage ponters */ struct brcmf_bus *bus_if; - struct brcmf_proto *prot; + struct brcmf_proto *proto; struct brcmf_cfg80211_info *config; /* Internal brcmf items */ @@ -635,28 +635,6 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev); /* Return pointer to interface name */ char *brcmf_ifname(struct brcmf_pub *drvr, int idx); -/* Linkage, sets prot link and updates hdrlen in pub */ -int brcmf_proto_attach(struct brcmf_pub *drvr); - -/* Unlink, frees allocated protocol memory (including brcmf_proto) */ -void brcmf_proto_detach(struct brcmf_pub *drvr); - -/* Add any protocol-specific data header. - * Caller must reserve prot_hdrlen prepend space. - */ -void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, - struct sk_buff *txp); - -/* Query dongle */ -int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len); -int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len); - -/* Remove any protocol-specific data header. */ -int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, - struct sk_buff *rxp); - int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, char *name, u8 *mac_addr); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 9336f6d..644e62e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -30,6 +30,7 @@ #include "wl_cfg80211.h" #include "fwil.h" #include "fwsignal.h" +#include "proto.h" MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); @@ -1040,8 +1041,7 @@ void brcmf_detach(struct device *dev) brcmf_bus_detach(drvr); - if (drvr->prot) - brcmf_proto_detach(drvr); + brcmf_proto_detach(drvr); brcmf_fws_deinit(drvr); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 04f3959..b72d339 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -27,6 +27,7 @@ #include "dhd_dbg.h" #include "tracepoint.h" #include "fwil.h" +#include "proto.h" #define MAX_HEX_DUMP_LEN 64 @@ -46,11 +47,9 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) if (data != NULL) len = min_t(uint, len, BRCMF_DCMD_MAXLEN); if (set) - err = brcmf_proto_cdc_set_dcmd(drvr, ifp->ifidx, cmd, data, - len); + err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len); else - err = brcmf_proto_cdc_query_dcmd(drvr, ifp->ifidx, cmd, data, - len); + err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); if (err >= 0) err = 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index b96ee3a..e9bdfdb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -35,6 +35,7 @@ #include "fwsignal.h" #include "p2p.h" #include "wl_cfg80211.h" +#include "proto.h" /** * DOC: Firmware Signalling diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c new file mode 100644 index 0000000..87eb2bd --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + + #include +#include +#include + +#include +#include "dhd.h" +#include "dhd_dbg.h" +#include "proto.h" +#include "bcdc.h" + + +int brcmf_proto_attach(struct brcmf_pub *drvr) +{ + struct brcmf_proto *proto; + + proto = kzalloc(sizeof(*proto), GFP_ATOMIC); + if (!proto) + goto fail; + + drvr->proto = proto; + /* BCDC protocol is only protocol supported for the moment */ + if (brcmf_proto_bcdc_attach(drvr)) + goto fail; + + if ((proto->hdrpush == NULL) || (proto->hdrpull == NULL) || + (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) { + brcmf_err("Not all proto handlers have been installed\n"); + goto fail; + } + return 0; + +fail: + kfree(proto); + drvr->proto = NULL; + return -ENOMEM; +} + +void brcmf_proto_detach(struct brcmf_pub *drvr) +{ + if (drvr->proto) { + brcmf_proto_bcdc_detach(drvr); + kfree(drvr->proto); + drvr->proto = NULL; + } +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h new file mode 100644 index 0000000..8de1b3b --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BRCMFMAC_PROTO_H +#define BRCMFMAC_PROTO_H + +struct brcmf_proto { + void (*hdrpush)(struct brcmf_pub *drvr, int ifidx, u8 offset, + struct sk_buff *skb); + int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, + struct sk_buff *skb); + int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len); + int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, + uint len); + void *pd; +}; + + +int brcmf_proto_attach(struct brcmf_pub *drvr); +void brcmf_proto_detach(struct brcmf_pub *drvr); + +static inline void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, + u8 offset, struct sk_buff *skb) +{ + drvr->proto->hdrpush(drvr, ifidx, offset, skb); +} +static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, + u8 *ifidx, struct sk_buff *skb) +{ + return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb); +} +static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx, + uint cmd, void *buf, uint len) +{ + return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len); +} +static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx, + uint cmd, void *buf, uint len) +{ + return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); +} + + +#endif /* BRCMFMAC_PROTO_H */ -- cgit v1.1 From 55685b8f2f9f419b1b1c5abf78a5c82f01ef0fe3 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:17 +0100 Subject: brcmfmac: provide firmware version in ethtool driver info Knowing the firmware version is pretty useful information when looking at issues. It is retrieved during initialization so store it in driver data structure to fill the ethtool driver info when requested. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 7 ++++++- drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | 5 +++++ drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 ++-- 3 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 4ed7a97..714194c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -211,6 +211,11 @@ #define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256 +/* Length of firmware version string stored for + * ethtool driver info which uses 32 bytes as well. + */ +#define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 + /* Pattern matching filter. Specifies an offset within received packets to * start matching, the pattern to match, the size of the pattern, and a bitmask * that indicates which bits within the pattern should be matched. @@ -544,7 +549,7 @@ struct brcmf_pub { u8 wme_dp; /* wme discard priority */ /* Dongle media info */ - unsigned long drv_version; /* Version of dongle-resident driver */ + char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN]; u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ /* Multicast data packets sent to dongle */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 6017633..d5811a4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -278,9 +278,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) } ptr = (char *)buf; strsep(&ptr, "\n"); + /* Print fw version info */ brcmf_err("Firmware version = %s\n", buf); + /* locate firmware version number for ethtool */ + ptr = strrchr(buf, ' ') + 1; + strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver)); + /* * Setup timeout if Beacons are lost and roam is off to report * link down diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 644e62e..bce0b8e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -599,8 +599,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, struct brcmf_pub *drvr = ifp->drvr; strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); - snprintf(info->version, sizeof(info->version), "%lu", - drvr->drv_version); + snprintf(info->version, sizeof(info->version), "n/a"); + strlcpy(info->fw_version, drvr->fwver, sizeof(info->fw_version)); strlcpy(info->bus_info, dev_name(drvr->bus_if->dev), sizeof(info->bus_info)); } -- cgit v1.1 From 84c69fb164cb0713c3e95bd190611f196d24c5b5 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:18 +0100 Subject: brcmfmac: remove unnecessary EXPORT_SYMBOL() usage In bcmsdh.c the functions brcmf_sdio_probe() and brcmf_sdio_remove() were exported, but that is not needed. The functions are linked into the driver module, which is the only one needing to call these. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3e10b80..91651ec 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -774,7 +773,6 @@ out: return ret; } -EXPORT_SYMBOL(brcmf_sdio_probe); int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) { @@ -791,7 +789,6 @@ int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) return 0; } -EXPORT_SYMBOL(brcmf_sdio_remove); void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) { -- cgit v1.1 From 6f5838a48aad77defef5e2ed91608e862309e351 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:19 +0100 Subject: brcmfmac: move firmware related structures to fwil_types.h The firmware control interface is provided by fwil source file, but a number of structures used to communicate with the firmware still resided in dhd.h. The patch moves them to fwil_types.h. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 306 --------------------- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 1 + .../net/wireless/brcm80211/brcmfmac/fwil_types.h | 304 ++++++++++++++++++++ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 10 +- 4 files changed, 310 insertions(+), 311 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 714194c..7806155 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -100,31 +100,11 @@ #define TOE_TX_CSUM_OL 0x00000001 #define TOE_RX_CSUM_OL 0x00000002 -#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ - -/* size of brcmf_scan_params not including variable length array */ -#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 - -/* masks for channel and ssid count */ -#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff -#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 - -/* primary (ie tx) key */ -#define BRCMF_PRIMARY_KEY (1 << 1) - /* For supporting multiple interfaces */ #define BRCMF_MAX_IFS 16 -#define DOT11_BSSTYPE_ANY 2 #define DOT11_MAX_DEFAULT_KEYS 4 -#define BRCMF_ESCAN_REQ_VERSION 1 - -#define WLC_BSS_RSSI_ON_CHANNEL 0x0002 - -#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ -#define BRCMF_STA_ASSOC 0x10 /* Associated */ - #define BRCMF_E_STATUS_SUCCESS 0 #define BRCMF_E_STATUS_FAIL 1 #define BRCMF_E_STATUS_TIMEOUT 2 @@ -216,292 +196,6 @@ */ #define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 -/* Pattern matching filter. Specifies an offset within received packets to - * start matching, the pattern to match, the size of the pattern, and a bitmask - * that indicates which bits within the pattern should be matched. - */ -struct brcmf_pkt_filter_pattern_le { - /* - * Offset within received packet to start pattern matching. - * Offset '0' is the first byte of the ethernet header. - */ - __le32 offset; - /* Size of the pattern. Bitmask must be the same size.*/ - __le32 size_bytes; - /* - * Variable length mask and pattern data. mask starts at offset 0. - * Pattern immediately follows mask. - */ - u8 mask_and_pattern[1]; -}; - -/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ -struct brcmf_pkt_filter_le { - __le32 id; /* Unique filter id, specified by app. */ - __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ - __le32 negate_match; /* Negate the result of filter matches */ - union { /* Filter definitions */ - struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */ - } u; -}; - -/* IOVAR "pkt_filter_enable" parameter. */ -struct brcmf_pkt_filter_enable_le { - __le32 id; /* Unique filter id */ - __le32 enable; /* Enable/disable bool */ -}; - -/* BSS info structure - * Applications MUST CHECK ie_offset field and length field to access IEs and - * next bss_info structure in a vector (in struct brcmf_scan_results) - */ -struct brcmf_bss_info_le { - __le32 version; /* version field */ - __le32 length; /* byte length of data in this record, - * starting at version and including IEs - */ - u8 BSSID[ETH_ALEN]; - __le16 beacon_period; /* units are Kusec */ - __le16 capability; /* Capability information */ - u8 SSID_len; - u8 SSID[32]; - struct { - __le32 count; /* # rates in this set */ - u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ - } rateset; /* supported rates */ - __le16 chanspec; /* chanspec for bss */ - __le16 atim_window; /* units are Kusec */ - u8 dtim_period; /* DTIM period */ - __le16 RSSI; /* receive signal strength (in dBm) */ - s8 phy_noise; /* noise (in dBm) */ - - u8 n_cap; /* BSS is 802.11N Capable */ - /* 802.11N BSS Capabilities (based on HT_CAP_*): */ - __le32 nbss_cap; - u8 ctl_ch; /* 802.11N BSS control channel number */ - __le32 reserved32[1]; /* Reserved for expansion of BSS properties */ - u8 flags; /* flags */ - u8 reserved[3]; /* Reserved for expansion of BSS properties */ - u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ - - __le16 ie_offset; /* offset at which IEs start, from beginning */ - __le32 ie_length; /* byte length of Information Elements */ - __le16 SNR; /* average SNR of during frame reception */ - /* Add new fields here */ - /* variable length Information Elements */ -}; - -struct brcm_rateset_le { - /* # rates in this set */ - __le32 count; - /* rates in 500kbps units w/hi bit set if basic */ - u8 rates[BRCMF_MAXRATES_IN_SET]; -}; - -struct brcmf_ssid { - u32 SSID_len; - unsigned char SSID[32]; -}; - -struct brcmf_ssid_le { - __le32 SSID_len; - unsigned char SSID[32]; -}; - -struct brcmf_scan_params_le { - struct brcmf_ssid_le ssid_le; /* default: {0, ""} */ - u8 bssid[ETH_ALEN]; /* default: bcast */ - s8 bss_type; /* default: any, - * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT - */ - u8 scan_type; /* flags, 0 use default */ - __le32 nprobes; /* -1 use default, number of probes per channel */ - __le32 active_time; /* -1 use default, dwell time per channel for - * active scanning - */ - __le32 passive_time; /* -1 use default, dwell time per channel - * for passive scanning - */ - __le32 home_time; /* -1 use default, dwell time for the - * home channel between channel scans - */ - __le32 channel_num; /* count of channels and ssids that follow - * - * low half is count of channels in - * channel_list, 0 means default (use all - * available channels) - * - * high half is entries in struct brcmf_ssid - * array that follows channel_list, aligned for - * s32 (4 bytes) meaning an odd channel count - * implies a 2-byte pad between end of - * channel_list and first ssid - * - * if ssid count is zero, single ssid in the - * fixed parameter portion is assumed, otherwise - * ssid in the fixed portion is ignored - */ - __le16 channel_list[1]; /* list of chanspecs */ -}; - -struct brcmf_scan_results { - u32 buflen; - u32 version; - u32 count; - struct brcmf_bss_info_le bss_info_le[]; -}; - -struct brcmf_escan_params_le { - __le32 version; - __le16 action; - __le16 sync_id; - struct brcmf_scan_params_le params_le; -}; - -struct brcmf_escan_result_le { - __le32 buflen; - __le32 version; - __le16 sync_id; - __le16 bss_count; - struct brcmf_bss_info_le bss_info_le; -}; - -#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \ - sizeof(struct brcmf_bss_info_le)) - -/* used for association with a specific BSSID and chanspec list */ -struct brcmf_assoc_params_le { - /* 00:00:00:00:00:00: broadcast scan */ - u8 bssid[ETH_ALEN]; - /* 0: all available channels, otherwise count of chanspecs in - * chanspec_list */ - __le32 chanspec_num; - /* list of chanspecs */ - __le16 chanspec_list[1]; -}; - -/* used for join with or without a specific bssid and channel list */ -struct brcmf_join_params { - struct brcmf_ssid_le ssid_le; - struct brcmf_assoc_params_le params_le; -}; - -/* scan params for extended join */ -struct brcmf_join_scan_params_le { - u8 scan_type; /* 0 use default, active or passive scan */ - __le32 nprobes; /* -1 use default, nr of probes per channel */ - __le32 active_time; /* -1 use default, dwell time per channel for - * active scanning - */ - __le32 passive_time; /* -1 use default, dwell time per channel - * for passive scanning - */ - __le32 home_time; /* -1 use default, dwell time for the home - * channel between channel scans - */ -}; - -/* extended join params */ -struct brcmf_ext_join_params_le { - struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */ - struct brcmf_join_scan_params_le scan_le; - struct brcmf_assoc_params_le assoc_le; -}; - -struct brcmf_wsec_key { - u32 index; /* key index */ - u32 len; /* key length */ - u8 data[WLAN_MAX_KEY_LEN]; /* key data */ - u32 pad_1[18]; - u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u32 flags; /* misc flags */ - u32 pad_2[3]; - u32 iv_initialized; /* has IV been initialized already? */ - u32 pad_3; - /* Rx IV */ - struct { - u32 hi; /* upper 32 bits of IV */ - u16 lo; /* lower 16 bits of IV */ - } rxiv; - u32 pad_4[2]; - u8 ea[ETH_ALEN]; /* per station */ -}; - -/* - * dongle requires same struct as above but with fields in little endian order - */ -struct brcmf_wsec_key_le { - __le32 index; /* key index */ - __le32 len; /* key length */ - u8 data[WLAN_MAX_KEY_LEN]; /* key data */ - __le32 pad_1[18]; - __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - __le32 flags; /* misc flags */ - __le32 pad_2[3]; - __le32 iv_initialized; /* has IV been initialized already? */ - __le32 pad_3; - /* Rx IV */ - struct { - __le32 hi; /* upper 32 bits of IV */ - __le16 lo; /* lower 16 bits of IV */ - } rxiv; - __le32 pad_4[2]; - u8 ea[ETH_ALEN]; /* per station */ -}; - -/* Used to get specific STA parameters */ -struct brcmf_scb_val_le { - __le32 val; - u8 ea[ETH_ALEN]; -}; - -/* channel encoding */ -struct brcmf_channel_info_le { - __le32 hw_channel; - __le32 target_channel; - __le32 scan_channel; -}; - -struct brcmf_sta_info_le { - __le16 ver; /* version of this struct */ - __le16 len; /* length in bytes of this structure */ - __le16 cap; /* sta's advertised capabilities */ - __le32 flags; /* flags defined below */ - __le32 idle; /* time since data pkt rx'd from sta */ - u8 ea[ETH_ALEN]; /* Station address */ - __le32 count; /* # rates in this set */ - u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ - /* w/hi bit set if basic */ - __le32 in; /* seconds elapsed since associated */ - __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ - __le32 tx_pkts; /* # of packets transmitted */ - __le32 tx_failures; /* # of packets failed */ - __le32 rx_ucast_pkts; /* # of unicast packets received */ - __le32 rx_mcast_pkts; /* # of multicast packets received */ - __le32 tx_rate; /* Rate of last successful tx frame */ - __le32 rx_rate; /* Rate of last successful rx frame */ - __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ - __le32 rx_decrypt_failures; /* # of packet decrypted failed */ -}; - -struct brcmf_chanspec_list { - __le32 count; /* # of entries */ - __le32 element[1]; /* variable length uint32 list */ -}; - -/* - * WLC_E_PROBRESP_MSG - * WLC_E_P2P_PROBREQ_MSG - * WLC_E_ACTION_FRAME_RX - */ -struct brcmf_rx_mgmt_data { - __be16 version; - __be16 chanspec; - __be32 rssi; - __be32 mactime; - __be32 rate; -}; - /* Bus independent dongle command */ struct brcmf_dcmd { uint cmd; /* common dongle cmd definition */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index d5811a4..548dbb5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -23,6 +23,7 @@ #include "dhd_bus.h" #include "dhd_dbg.h" #include "fwil.h" +#include "fwil_types.h" #include "tracepoint.h" #define PKTFILTER_BUF_SIZE 128 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h index ecabb04..af17a5b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h @@ -29,6 +29,24 @@ #define BRCMF_ARP_OL_HOST_AUTO_REPLY 0x00000004 #define BRCMF_ARP_OL_PEER_AUTO_REPLY 0x00000008 +#define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ +#define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 + +#define BRCMF_STA_ASSOC 0x10 /* Associated */ + +/* size of brcmf_scan_params not including variable length array */ +#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 + +/* masks for channel and ssid count */ +#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff +#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 + +/* primary (ie tx) key */ +#define BRCMF_PRIMARY_KEY (1 << 1) +#define DOT11_BSSTYPE_ANY 2 +#define BRCMF_ESCAN_REQ_VERSION 1 + +#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ enum brcmf_fil_p2p_if_types { BRCMF_FIL_P2P_IF_CLIENT, @@ -90,4 +108,290 @@ enum brcmf_tdls_manual_ep_ops { BRCMF_TDLS_MANUAL_EP_DISCOVERY = 6 }; +/* Pattern matching filter. Specifies an offset within received packets to + * start matching, the pattern to match, the size of the pattern, and a bitmask + * that indicates which bits within the pattern should be matched. + */ +struct brcmf_pkt_filter_pattern_le { + /* + * Offset within received packet to start pattern matching. + * Offset '0' is the first byte of the ethernet header. + */ + __le32 offset; + /* Size of the pattern. Bitmask must be the same size.*/ + __le32 size_bytes; + /* + * Variable length mask and pattern data. mask starts at offset 0. + * Pattern immediately follows mask. + */ + u8 mask_and_pattern[1]; +}; + +/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ +struct brcmf_pkt_filter_le { + __le32 id; /* Unique filter id, specified by app. */ + __le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */ + __le32 negate_match; /* Negate the result of filter matches */ + union { /* Filter definitions */ + struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */ + } u; +}; + +/* IOVAR "pkt_filter_enable" parameter. */ +struct brcmf_pkt_filter_enable_le { + __le32 id; /* Unique filter id */ + __le32 enable; /* Enable/disable bool */ +}; + +/* BSS info structure + * Applications MUST CHECK ie_offset field and length field to access IEs and + * next bss_info structure in a vector (in struct brcmf_scan_results) + */ +struct brcmf_bss_info_le { + __le32 version; /* version field */ + __le32 length; /* byte length of data in this record, + * starting at version and including IEs + */ + u8 BSSID[ETH_ALEN]; + __le16 beacon_period; /* units are Kusec */ + __le16 capability; /* Capability information */ + u8 SSID_len; + u8 SSID[32]; + struct { + __le32 count; /* # rates in this set */ + u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + } rateset; /* supported rates */ + __le16 chanspec; /* chanspec for bss */ + __le16 atim_window; /* units are Kusec */ + u8 dtim_period; /* DTIM period */ + __le16 RSSI; /* receive signal strength (in dBm) */ + s8 phy_noise; /* noise (in dBm) */ + + u8 n_cap; /* BSS is 802.11N Capable */ + /* 802.11N BSS Capabilities (based on HT_CAP_*): */ + __le32 nbss_cap; + u8 ctl_ch; /* 802.11N BSS control channel number */ + __le32 reserved32[1]; /* Reserved for expansion of BSS properties */ + u8 flags; /* flags */ + u8 reserved[3]; /* Reserved for expansion of BSS properties */ + u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ + + __le16 ie_offset; /* offset at which IEs start, from beginning */ + __le32 ie_length; /* byte length of Information Elements */ + __le16 SNR; /* average SNR of during frame reception */ + /* Add new fields here */ + /* variable length Information Elements */ +}; + +struct brcm_rateset_le { + /* # rates in this set */ + __le32 count; + /* rates in 500kbps units w/hi bit set if basic */ + u8 rates[BRCMF_MAXRATES_IN_SET]; +}; + +struct brcmf_ssid { + u32 SSID_len; + unsigned char SSID[32]; +}; + +struct brcmf_ssid_le { + __le32 SSID_len; + unsigned char SSID[32]; +}; + +struct brcmf_scan_params_le { + struct brcmf_ssid_le ssid_le; /* default: {0, ""} */ + u8 bssid[ETH_ALEN]; /* default: bcast */ + s8 bss_type; /* default: any, + * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT + */ + u8 scan_type; /* flags, 0 use default */ + __le32 nprobes; /* -1 use default, number of probes per channel */ + __le32 active_time; /* -1 use default, dwell time per channel for + * active scanning + */ + __le32 passive_time; /* -1 use default, dwell time per channel + * for passive scanning + */ + __le32 home_time; /* -1 use default, dwell time for the + * home channel between channel scans + */ + __le32 channel_num; /* count of channels and ssids that follow + * + * low half is count of channels in + * channel_list, 0 means default (use all + * available channels) + * + * high half is entries in struct brcmf_ssid + * array that follows channel_list, aligned for + * s32 (4 bytes) meaning an odd channel count + * implies a 2-byte pad between end of + * channel_list and first ssid + * + * if ssid count is zero, single ssid in the + * fixed parameter portion is assumed, otherwise + * ssid in the fixed portion is ignored + */ + __le16 channel_list[1]; /* list of chanspecs */ +}; + +struct brcmf_scan_results { + u32 buflen; + u32 version; + u32 count; + struct brcmf_bss_info_le bss_info_le[]; +}; + +struct brcmf_escan_params_le { + __le32 version; + __le16 action; + __le16 sync_id; + struct brcmf_scan_params_le params_le; +}; + +struct brcmf_escan_result_le { + __le32 buflen; + __le32 version; + __le16 sync_id; + __le16 bss_count; + struct brcmf_bss_info_le bss_info_le; +}; + +#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \ + sizeof(struct brcmf_bss_info_le)) + +/* used for association with a specific BSSID and chanspec list */ +struct brcmf_assoc_params_le { + /* 00:00:00:00:00:00: broadcast scan */ + u8 bssid[ETH_ALEN]; + /* 0: all available channels, otherwise count of chanspecs in + * chanspec_list */ + __le32 chanspec_num; + /* list of chanspecs */ + __le16 chanspec_list[1]; +}; + +/* used for join with or without a specific bssid and channel list */ +struct brcmf_join_params { + struct brcmf_ssid_le ssid_le; + struct brcmf_assoc_params_le params_le; +}; + +/* scan params for extended join */ +struct brcmf_join_scan_params_le { + u8 scan_type; /* 0 use default, active or passive scan */ + __le32 nprobes; /* -1 use default, nr of probes per channel */ + __le32 active_time; /* -1 use default, dwell time per channel for + * active scanning + */ + __le32 passive_time; /* -1 use default, dwell time per channel + * for passive scanning + */ + __le32 home_time; /* -1 use default, dwell time for the home + * channel between channel scans + */ +}; + +/* extended join params */ +struct brcmf_ext_join_params_le { + struct brcmf_ssid_le ssid_le; /* {0, ""}: wildcard scan */ + struct brcmf_join_scan_params_le scan_le; + struct brcmf_assoc_params_le assoc_le; +}; + +struct brcmf_wsec_key { + u32 index; /* key index */ + u32 len; /* key length */ + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ + u32 pad_1[18]; + u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u32 flags; /* misc flags */ + u32 pad_2[3]; + u32 iv_initialized; /* has IV been initialized already? */ + u32 pad_3; + /* Rx IV */ + struct { + u32 hi; /* upper 32 bits of IV */ + u16 lo; /* lower 16 bits of IV */ + } rxiv; + u32 pad_4[2]; + u8 ea[ETH_ALEN]; /* per station */ +}; + +/* + * dongle requires same struct as above but with fields in little endian order + */ +struct brcmf_wsec_key_le { + __le32 index; /* key index */ + __le32 len; /* key length */ + u8 data[WLAN_MAX_KEY_LEN]; /* key data */ + __le32 pad_1[18]; + __le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + __le32 flags; /* misc flags */ + __le32 pad_2[3]; + __le32 iv_initialized; /* has IV been initialized already? */ + __le32 pad_3; + /* Rx IV */ + struct { + __le32 hi; /* upper 32 bits of IV */ + __le16 lo; /* lower 16 bits of IV */ + } rxiv; + __le32 pad_4[2]; + u8 ea[ETH_ALEN]; /* per station */ +}; + +/* Used to get specific STA parameters */ +struct brcmf_scb_val_le { + __le32 val; + u8 ea[ETH_ALEN]; +}; + +/* channel encoding */ +struct brcmf_channel_info_le { + __le32 hw_channel; + __le32 target_channel; + __le32 scan_channel; +}; + +struct brcmf_sta_info_le { + __le16 ver; /* version of this struct */ + __le16 len; /* length in bytes of this structure */ + __le16 cap; /* sta's advertised capabilities */ + __le32 flags; /* flags defined below */ + __le32 idle; /* time since data pkt rx'd from sta */ + u8 ea[ETH_ALEN]; /* Station address */ + __le32 count; /* # rates in this set */ + u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ + /* w/hi bit set if basic */ + __le32 in; /* seconds elapsed since associated */ + __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ + __le32 tx_pkts; /* # of packets transmitted */ + __le32 tx_failures; /* # of packets failed */ + __le32 rx_ucast_pkts; /* # of unicast packets received */ + __le32 rx_mcast_pkts; /* # of multicast packets received */ + __le32 tx_rate; /* Rate of last successful tx frame */ + __le32 rx_rate; /* Rate of last successful rx frame */ + __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ + __le32 rx_decrypt_failures; /* # of packet decrypted failed */ +}; + +struct brcmf_chanspec_list { + __le32 count; /* # of entries */ + __le32 element[1]; /* variable length uint32 list */ +}; + +/* + * WLC_E_PROBRESP_MSG + * WLC_E_P2P_PROBREQ_MSG + * WLC_E_ACTION_FRAME_RX + */ +struct brcmf_rx_mgmt_data { + __be16 version; + __be16 chanspec; + __be32 rssi; + __be32 mactime; + __be32 rate; +}; + #endif /* FWIL_TYPES_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 571f013..470a47f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2556,8 +2556,8 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg, ch_bss.band == ch_bss_info_le.band && bss_info_le->SSID_len == bss->SSID_len && !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) { - if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) == - (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) { + if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == + (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) { s16 bss_rssi = le16_to_cpu(bss->RSSI); s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI); @@ -2566,13 +2566,13 @@ brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg, */ if (bss_info_rssi > bss_rssi) bss->RSSI = bss_info_le->RSSI; - } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) && - (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) { + } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) && + (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) { /* preserve the on-channel rssi measurement * if the new measurement is off channel */ bss->RSSI = bss_info_le->RSSI; - bss->flags |= WLC_BSS_RSSI_ON_CHANNEL; + bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL; } return 1; } -- cgit v1.1 From 5ca85216b173ebac0aa523e4dd826d82d530a465 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:20 +0100 Subject: brcmfmac: move firmware command code definitions Move the command codes to the firmware interface module as that makes a bit more sense. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 61 -------------------------- drivers/net/wireless/brcm80211/brcmfmac/fwil.h | 61 ++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 61 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 7806155..a85f9db 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -25,67 +25,6 @@ #include "fweh.h" -/******************************************************************************* - * IO codes that are interpreted by dongle firmware - ******************************************************************************/ -#define BRCMF_C_GET_VERSION 1 -#define BRCMF_C_UP 2 -#define BRCMF_C_DOWN 3 -#define BRCMF_C_SET_PROMISC 10 -#define BRCMF_C_GET_RATE 12 -#define BRCMF_C_GET_INFRA 19 -#define BRCMF_C_SET_INFRA 20 -#define BRCMF_C_GET_AUTH 21 -#define BRCMF_C_SET_AUTH 22 -#define BRCMF_C_GET_BSSID 23 -#define BRCMF_C_GET_SSID 25 -#define BRCMF_C_SET_SSID 26 -#define BRCMF_C_TERMINATED 28 -#define BRCMF_C_GET_CHANNEL 29 -#define BRCMF_C_SET_CHANNEL 30 -#define BRCMF_C_GET_SRL 31 -#define BRCMF_C_SET_SRL 32 -#define BRCMF_C_GET_LRL 33 -#define BRCMF_C_SET_LRL 34 -#define BRCMF_C_GET_RADIO 37 -#define BRCMF_C_SET_RADIO 38 -#define BRCMF_C_GET_PHYTYPE 39 -#define BRCMF_C_SET_KEY 45 -#define BRCMF_C_SET_PASSIVE_SCAN 49 -#define BRCMF_C_SCAN 50 -#define BRCMF_C_SCAN_RESULTS 51 -#define BRCMF_C_DISASSOC 52 -#define BRCMF_C_REASSOC 53 -#define BRCMF_C_SET_ROAM_TRIGGER 55 -#define BRCMF_C_SET_ROAM_DELTA 57 -#define BRCMF_C_GET_BCNPRD 75 -#define BRCMF_C_SET_BCNPRD 76 -#define BRCMF_C_GET_DTIMPRD 77 -#define BRCMF_C_SET_DTIMPRD 78 -#define BRCMF_C_SET_COUNTRY 84 -#define BRCMF_C_GET_PM 85 -#define BRCMF_C_SET_PM 86 -#define BRCMF_C_GET_CURR_RATESET 114 -#define BRCMF_C_GET_AP 117 -#define BRCMF_C_SET_AP 118 -#define BRCMF_C_GET_RSSI 127 -#define BRCMF_C_GET_WSEC 133 -#define BRCMF_C_SET_WSEC 134 -#define BRCMF_C_GET_PHY_NOISE 135 -#define BRCMF_C_GET_BSS_INFO 136 -#define BRCMF_C_GET_BANDLIST 140 -#define BRCMF_C_SET_SCB_TIMEOUT 158 -#define BRCMF_C_GET_PHYLIST 180 -#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 -#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 -#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 -#define BRCMF_C_GET_VALID_CHANNELS 217 -#define BRCMF_C_GET_KEY_PRIMARY 235 -#define BRCMF_C_SET_KEY_PRIMARY 236 -#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258 -#define BRCMF_C_GET_VAR 262 -#define BRCMF_C_SET_VAR 263 - /* phy types (returned by WLC_GET_PHYTPE) */ #define WLC_PHY_TYPE_A 0 #define WLC_PHY_TYPE_B 1 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h index 16eb820..77eae86 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h @@ -17,6 +17,67 @@ #ifndef _fwil_h_ #define _fwil_h_ +/******************************************************************************* + * Dongle command codes that are interpreted by firmware + ******************************************************************************/ +#define BRCMF_C_GET_VERSION 1 +#define BRCMF_C_UP 2 +#define BRCMF_C_DOWN 3 +#define BRCMF_C_SET_PROMISC 10 +#define BRCMF_C_GET_RATE 12 +#define BRCMF_C_GET_INFRA 19 +#define BRCMF_C_SET_INFRA 20 +#define BRCMF_C_GET_AUTH 21 +#define BRCMF_C_SET_AUTH 22 +#define BRCMF_C_GET_BSSID 23 +#define BRCMF_C_GET_SSID 25 +#define BRCMF_C_SET_SSID 26 +#define BRCMF_C_TERMINATED 28 +#define BRCMF_C_GET_CHANNEL 29 +#define BRCMF_C_SET_CHANNEL 30 +#define BRCMF_C_GET_SRL 31 +#define BRCMF_C_SET_SRL 32 +#define BRCMF_C_GET_LRL 33 +#define BRCMF_C_SET_LRL 34 +#define BRCMF_C_GET_RADIO 37 +#define BRCMF_C_SET_RADIO 38 +#define BRCMF_C_GET_PHYTYPE 39 +#define BRCMF_C_SET_KEY 45 +#define BRCMF_C_SET_PASSIVE_SCAN 49 +#define BRCMF_C_SCAN 50 +#define BRCMF_C_SCAN_RESULTS 51 +#define BRCMF_C_DISASSOC 52 +#define BRCMF_C_REASSOC 53 +#define BRCMF_C_SET_ROAM_TRIGGER 55 +#define BRCMF_C_SET_ROAM_DELTA 57 +#define BRCMF_C_GET_BCNPRD 75 +#define BRCMF_C_SET_BCNPRD 76 +#define BRCMF_C_GET_DTIMPRD 77 +#define BRCMF_C_SET_DTIMPRD 78 +#define BRCMF_C_SET_COUNTRY 84 +#define BRCMF_C_GET_PM 85 +#define BRCMF_C_SET_PM 86 +#define BRCMF_C_GET_CURR_RATESET 114 +#define BRCMF_C_GET_AP 117 +#define BRCMF_C_SET_AP 118 +#define BRCMF_C_GET_RSSI 127 +#define BRCMF_C_GET_WSEC 133 +#define BRCMF_C_SET_WSEC 134 +#define BRCMF_C_GET_PHY_NOISE 135 +#define BRCMF_C_GET_BSS_INFO 136 +#define BRCMF_C_GET_BANDLIST 140 +#define BRCMF_C_SET_SCB_TIMEOUT 158 +#define BRCMF_C_GET_PHYLIST 180 +#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 +#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 +#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 +#define BRCMF_C_GET_VALID_CHANNELS 217 +#define BRCMF_C_GET_KEY_PRIMARY 235 +#define BRCMF_C_SET_KEY_PRIMARY 236 +#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258 +#define BRCMF_C_GET_VAR 262 +#define BRCMF_C_SET_VAR 263 + s32 brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); s32 brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len); s32 brcmf_fil_cmd_int_set(struct brcmf_if *ifp, u32 cmd, u32 data); -- cgit v1.1 From aec87ce2f38c54dc7ef9bff2038e3b102a4e6c0c Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Fri, 29 Nov 2013 12:25:21 +0100 Subject: brcmfmac: Use consistent naming for BCDC. The BCDC protocol layer is using a mix of naming of CDC, BDC and BCDC. Use the name BCDC consistenly over all functions, defines and variables. This patch does not change code functionality. Reviewed-by: Arend Van Spriel Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 195 ++++++++++----------- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 2 +- .../net/wireless/brcm80211/brcmfmac/tracepoint.h | 4 +- 3 files changed, 95 insertions(+), 106 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index b5a2529..06848e4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -33,7 +33,7 @@ #include "proto.h" #include "bcdc.h" -struct brcmf_proto_cdc_dcmd { +struct brcmf_proto_bcdc_dcmd { __le32 cmd; /* dongle command value */ __le32 len; /* lower 16: output buflen; * upper 16: input buflen (excludes header) */ @@ -42,47 +42,47 @@ struct brcmf_proto_cdc_dcmd { }; /* Max valid buffer size that can be sent to the dongle */ -#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) - -/* CDC flag definitions */ -#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */ -#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ -#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */ -#define CDC_DCMD_IF_SHIFT 12 -#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */ -#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */ -#define CDC_DCMD_ID(flags) \ - (((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT) +#define BCDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) + +/* BCDC flag definitions */ +#define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */ +#define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ +#define BCDC_DCMD_IF_MASK 0xF000 /* I/F index */ +#define BCDC_DCMD_IF_SHIFT 12 +#define BCDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */ +#define BCDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */ +#define BCDC_DCMD_ID(flags) \ + (((flags) & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT) /* - * BDC header - Broadcom specific extension of CDC. + * BCDC header - Broadcom specific extension of CDC. * Used on data packets to convey priority across USB. */ -#define BDC_HEADER_LEN 4 -#define BDC_PROTO_VER 2 /* Protocol version */ -#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ -#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ -#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ -#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ -#define BDC_PRIORITY_MASK 0x7 -#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ -#define BDC_FLAG2_IF_SHIFT 0 - -#define BDC_GET_IF_IDX(hdr) \ - ((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT)) -#define BDC_SET_IF_IDX(hdr, idx) \ - ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ - ((idx) << BDC_FLAG2_IF_SHIFT))) +#define BCDC_HEADER_LEN 4 +#define BCDC_PROTO_VER 2 /* Protocol version */ +#define BCDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */ +#define BCDC_FLAG_VER_SHIFT 4 /* Protocol version shift */ +#define BCDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */ +#define BCDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */ +#define BCDC_PRIORITY_MASK 0x7 +#define BCDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */ +#define BCDC_FLAG2_IF_SHIFT 0 + +#define BCDC_GET_IF_IDX(hdr) \ + ((int)((((hdr)->flags2) & BCDC_FLAG2_IF_MASK) >> BCDC_FLAG2_IF_SHIFT)) +#define BCDC_SET_IF_IDX(hdr, idx) \ + ((hdr)->flags2 = (((hdr)->flags2 & ~BCDC_FLAG2_IF_MASK) | \ + ((idx) << BCDC_FLAG2_IF_SHIFT))) /** - * struct brcmf_proto_bdc_header - BDC header format + * struct brcmf_proto_bcdc_header - BCDC header format * * @flags: flags contain protocol and checksum info. * @priority: 802.1d priority and USB flow control info (bit 4:7). * @flags2: additional flags containing dongle interface index. * @data_offset: start of packet data. header is following by firmware signals. */ -struct brcmf_proto_bdc_header { +struct brcmf_proto_bcdc_header { u8 flags; u8 priority; u8 flags2; @@ -91,7 +91,7 @@ struct brcmf_proto_bdc_header { /* * maximum length of firmware signal data between - * the BDC header and packet data in the tx path. + * the BCDC header and packet data in the tx path. */ #define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12 @@ -109,42 +109,42 @@ struct brcmf_proto_bdc_header { struct brcmf_bcdc { u16 reqid; u8 bus_header[BUS_HEADER_LEN]; - struct brcmf_proto_cdc_dcmd msg; + struct brcmf_proto_bcdc_dcmd msg; unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; }; -static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) +static int brcmf_proto_bcdc_msg(struct brcmf_pub *drvr) { struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; int len = le32_to_cpu(bcdc->msg.len) + - sizeof(struct brcmf_proto_cdc_dcmd); + sizeof(struct brcmf_proto_bcdc_dcmd); - brcmf_dbg(CDC, "Enter\n"); + brcmf_dbg(BCDC, "Enter\n"); - /* NOTE : cdc->msg.len holds the desired length of the buffer to be - * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area + /* NOTE : bcdc->msg.len holds the desired length of the buffer to be + * returned. Only up to BCDC_MAX_MSG_SIZE of this buffer area * is actually sent to the dongle */ - if (len > CDC_MAX_MSG_SIZE) - len = CDC_MAX_MSG_SIZE; + if (len > BCDC_MAX_MSG_SIZE) + len = BCDC_MAX_MSG_SIZE; /* Send request */ return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); } -static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) +static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) { int ret; struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; - brcmf_dbg(CDC, "Enter\n"); - len += sizeof(struct brcmf_proto_cdc_dcmd); + brcmf_dbg(BCDC, "Enter\n"); + len += sizeof(struct brcmf_proto_bcdc_dcmd); do { ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); if (ret < 0) break; - } while (CDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id); + } while (BCDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id); return ret; } @@ -154,40 +154,40 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len) { struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; - struct brcmf_proto_cdc_dcmd *msg = &bcdc->msg; + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; void *info; int ret = 0, retries = 0; u32 id, flags; - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); + brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); - memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); + memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd)); msg->cmd = cpu_to_le32(cmd); msg->len = cpu_to_le32(len); - flags = (++bcdc->reqid << CDC_DCMD_ID_SHIFT); - flags = (flags & ~CDC_DCMD_IF_MASK) | - (ifidx << CDC_DCMD_IF_SHIFT); + flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT); + flags = (flags & ~BCDC_DCMD_IF_MASK) | + (ifidx << BCDC_DCMD_IF_SHIFT); msg->flags = cpu_to_le32(flags); if (buf) memcpy(bcdc->buf, buf, len); - ret = brcmf_proto_cdc_msg(drvr); + ret = brcmf_proto_bcdc_msg(drvr); if (ret < 0) { - brcmf_err("brcmf_proto_cdc_msg failed w/status %d\n", + brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", ret); goto done; } retry: /* wait for interrupt and get first fragment */ - ret = brcmf_proto_cdc_cmplt(drvr, bcdc->reqid, len); + ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len); if (ret < 0) goto done; flags = le32_to_cpu(msg->flags); - id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; + id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT; if ((id < bcdc->reqid) && (++retries < RETRIES)) goto retry; @@ -209,7 +209,7 @@ retry: } /* Check the ERROR flag */ - if (flags & CDC_DCMD_ERROR) + if (flags & BCDC_DCMD_ERROR) ret = le32_to_cpu(msg->status); done: @@ -221,34 +221,34 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len) { struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; - struct brcmf_proto_cdc_dcmd *msg = &bcdc->msg; + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; int ret = 0; u32 flags, id; - brcmf_dbg(CDC, "Enter, cmd %d len %d\n", cmd, len); + brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); - memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd)); + memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd)); msg->cmd = cpu_to_le32(cmd); msg->len = cpu_to_le32(len); - flags = (++bcdc->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET; - flags = (flags & ~CDC_DCMD_IF_MASK) | - (ifidx << CDC_DCMD_IF_SHIFT); + flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT) | BCDC_DCMD_SET; + flags = (flags & ~BCDC_DCMD_IF_MASK) | + (ifidx << BCDC_DCMD_IF_SHIFT); msg->flags = cpu_to_le32(flags); if (buf) memcpy(bcdc->buf, buf, len); - ret = brcmf_proto_cdc_msg(drvr); + ret = brcmf_proto_bcdc_msg(drvr); if (ret < 0) goto done; - ret = brcmf_proto_cdc_cmplt(drvr, bcdc->reqid, len); + ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len); if (ret < 0) goto done; flags = le32_to_cpu(msg->flags); - id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT; + id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT; if (id != bcdc->reqid) { brcmf_err("%s: unexpected request id %d (expected %d)\n", @@ -258,67 +258,56 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, } /* Check the ERROR flag */ - if (flags & CDC_DCMD_ERROR) + if (flags & BCDC_DCMD_ERROR) ret = le32_to_cpu(msg->status); done: return ret; } -static bool pkt_sum_needed(struct sk_buff *skb) -{ - return skb->ip_summed == CHECKSUM_PARTIAL; -} - -static void pkt_set_sum_good(struct sk_buff *skb, bool x) -{ - skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); -} - static void brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset, struct sk_buff *pktbuf) { - struct brcmf_proto_bdc_header *h; + struct brcmf_proto_bcdc_header *h; - brcmf_dbg(CDC, "Enter\n"); + brcmf_dbg(BCDC, "Enter\n"); /* Push BDC header used to convey priority for buses that don't */ - skb_push(pktbuf, BDC_HEADER_LEN); + skb_push(pktbuf, BCDC_HEADER_LEN); - h = (struct brcmf_proto_bdc_header *)(pktbuf->data); + h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); - h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); - if (pkt_sum_needed(pktbuf)) - h->flags |= BDC_FLAG_SUM_NEEDED; + h->flags = (BCDC_PROTO_VER << BCDC_FLAG_VER_SHIFT); + if (pktbuf->ip_summed == CHECKSUM_PARTIAL) + h->flags |= BCDC_FLAG_SUM_NEEDED; - h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); + h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK); h->flags2 = 0; h->data_offset = offset; - BDC_SET_IF_IDX(h, ifidx); - trace_brcmf_bdchdr(pktbuf->data); + BCDC_SET_IF_IDX(h, ifidx); + trace_brcmf_bcdchdr(pktbuf->data); } static int brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, struct sk_buff *pktbuf) { - struct brcmf_proto_bdc_header *h; - - brcmf_dbg(CDC, "Enter\n"); + struct brcmf_proto_bcdc_header *h; - /* Pop BDC header used to convey priority for buses that don't */ + brcmf_dbg(BCDC, "Enter\n"); - if (pktbuf->len <= BDC_HEADER_LEN) { + /* Pop BCDC header used to convey priority for buses that don't */ + if (pktbuf->len <= BCDC_HEADER_LEN) { brcmf_dbg(INFO, "rx data too short (%d <= %d)\n", - pktbuf->len, BDC_HEADER_LEN); + pktbuf->len, BCDC_HEADER_LEN); return -EBADE; } - trace_brcmf_bdchdr(pktbuf->data); - h = (struct brcmf_proto_bdc_header *)(pktbuf->data); + trace_brcmf_bcdchdr(pktbuf->data); + h = (struct brcmf_proto_bcdc_header *)(pktbuf->data); - *ifidx = BDC_GET_IF_IDX(h); + *ifidx = BCDC_GET_IF_IDX(h); if (*ifidx >= BRCMF_MAX_IFS) { brcmf_err("rx data ifnum out of range (%d)\n", *ifidx); return -EBADE; @@ -332,22 +321,22 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, if (*ifidx) (*ifidx)++; - if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != - BDC_PROTO_VER) { - brcmf_err("%s: non-BDC packet received, flags 0x%x\n", + if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != + BCDC_PROTO_VER) { + brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", brcmf_ifname(drvr, *ifidx), h->flags); return -EBADE; } - if (h->flags & BDC_FLAG_SUM_GOOD) { - brcmf_dbg(CDC, "%s: BDC rcv, good checksum, flags 0x%x\n", + if (h->flags & BCDC_FLAG_SUM_GOOD) { + brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n", brcmf_ifname(drvr, *ifidx), h->flags); - pkt_set_sum_good(pktbuf, true); + pktbuf->ip_summed = CHECKSUM_UNNECESSARY; } - pktbuf->priority = h->priority & BDC_PRIORITY_MASK; + pktbuf->priority = h->priority & BCDC_PRIORITY_MASK; - skb_pull(pktbuf, BDC_HEADER_LEN); + skb_pull(pktbuf, BCDC_HEADER_LEN); if (do_fws) brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); else @@ -378,9 +367,9 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd; drvr->proto->pd = bcdc; - drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; + drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + - sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; + sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN; return 0; fail: diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index 0af1f5d..ef52ed7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -33,7 +33,7 @@ #define BRCMF_USB_VAL 0x00002000 #define BRCMF_SCAN_VAL 0x00004000 #define BRCMF_CONN_VAL 0x00008000 -#define BRCMF_CDC_VAL 0x00010000 +#define BRCMF_BCDC_VAL 0x00010000 #define BRCMF_SDIO_VAL 0x00020000 /* set default print format */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h index d229cda..4d7d51f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h @@ -89,7 +89,7 @@ TRACE_EVENT(brcmf_hexdump, TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len) ); -TRACE_EVENT(brcmf_bdchdr, +TRACE_EVENT(brcmf_bcdchdr, TP_PROTO(void *data), TP_ARGS(data), TP_STRUCT__entry( @@ -107,7 +107,7 @@ TRACE_EVENT(brcmf_bdchdr, memcpy(__get_dynamic_array(signal), (u8 *)data + 4, __entry->siglen); ), - TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) + TP_printk("bcdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) ); #ifndef SDPCM_RX -- cgit v1.1 From b881879dea8d4bbfc71534d9dc5c9cf8298127a9 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:22 +0100 Subject: brcmfmac: remove some unused definitions Removing WLC_PHY_TYPE and some BRCMF_E_.* definitions as these are not used in the driver sources. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 48 --------------------------- 1 file changed, 48 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index a85f9db..da5cf00 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -25,17 +25,6 @@ #include "fweh.h" -/* phy types (returned by WLC_GET_PHYTPE) */ -#define WLC_PHY_TYPE_A 0 -#define WLC_PHY_TYPE_B 1 -#define WLC_PHY_TYPE_G 2 -#define WLC_PHY_TYPE_N 4 -#define WLC_PHY_TYPE_LP 5 -#define WLC_PHY_TYPE_SSN 6 -#define WLC_PHY_TYPE_HT 7 -#define WLC_PHY_TYPE_LCN 8 -#define WLC_PHY_TYPE_NULL 0xf - #define TOE_TX_CSUM_OL 0x00000001 #define TOE_RX_CSUM_OL 0x00000002 @@ -75,38 +64,6 @@ #define BRCMF_E_REASON_TSPEC_REJECTED 7 #define BRCMF_E_REASON_BETTER_AP 8 -#define BRCMF_E_PRUNE_ENCR_MISMATCH 1 -#define BRCMF_E_PRUNE_BCAST_BSSID 2 -#define BRCMF_E_PRUNE_MAC_DENY 3 -#define BRCMF_E_PRUNE_MAC_NA 4 -#define BRCMF_E_PRUNE_REG_PASSV 5 -#define BRCMF_E_PRUNE_SPCT_MGMT 6 -#define BRCMF_E_PRUNE_RADAR 7 -#define BRCMF_E_RSN_MISMATCH 8 -#define BRCMF_E_PRUNE_NO_COMMON_RATES 9 -#define BRCMF_E_PRUNE_BASIC_RATES 10 -#define BRCMF_E_PRUNE_CIPHER_NA 12 -#define BRCMF_E_PRUNE_KNOWN_STA 13 -#define BRCMF_E_PRUNE_WDS_PEER 15 -#define BRCMF_E_PRUNE_QBSS_LOAD 16 -#define BRCMF_E_PRUNE_HOME_AP 17 - -#define BRCMF_E_SUP_OTHER 0 -#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1 -#define BRCMF_E_SUP_BAD_UCAST_WEP128 2 -#define BRCMF_E_SUP_BAD_UCAST_WEP40 3 -#define BRCMF_E_SUP_UNSUP_KEY_LEN 4 -#define BRCMF_E_SUP_PW_KEY_CIPHER 5 -#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6 -#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7 -#define BRCMF_E_SUP_NO_INSTALL_FLAG 8 -#define BRCMF_E_SUP_MSG3_NO_GTK 9 -#define BRCMF_E_SUP_GRP_KEY_CIPHER 10 -#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11 -#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12 -#define BRCMF_E_SUP_SEND_FAIL 13 -#define BRCMF_E_SUP_DEAUTH 14 - #define BRCMF_E_IF_ADD 1 #define BRCMF_E_IF_DEL 2 #define BRCMF_E_IF_CHANGE 3 @@ -117,11 +74,6 @@ #define BRCMF_E_IF_ROLE_AP 1 #define BRCMF_E_IF_ROLE_WDS 2 -#define BRCMF_E_LINK_BCN_LOSS 1 -#define BRCMF_E_LINK_DISASSOC 2 -#define BRCMF_E_LINK_ASSOC_REC 3 -#define BRCMF_E_LINK_BSSCFG_DIS 4 - /* Small, medium and maximum buffer size for dcmd */ #define BRCMF_DCMD_SMLEN 256 -- cgit v1.1 From 01376a07bcf72fdad1ed5ed906025ca786d333dc Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:23 +0100 Subject: brcmfmac: move firmware event related defines to fweh.h The dhd.h file contained a number of definitions that are related to events received from the firmware. Those are processed and dispatched in the driver by fweh. Hence the definitions are moved to its include file. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 49 ----------------------- drivers/net/wireless/brcm80211/brcmfmac/fweh.h | 54 ++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 49 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index da5cf00..252024b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -33,47 +33,6 @@ #define DOT11_MAX_DEFAULT_KEYS 4 -#define BRCMF_E_STATUS_SUCCESS 0 -#define BRCMF_E_STATUS_FAIL 1 -#define BRCMF_E_STATUS_TIMEOUT 2 -#define BRCMF_E_STATUS_NO_NETWORKS 3 -#define BRCMF_E_STATUS_ABORT 4 -#define BRCMF_E_STATUS_NO_ACK 5 -#define BRCMF_E_STATUS_UNSOLICITED 6 -#define BRCMF_E_STATUS_ATTEMPT 7 -#define BRCMF_E_STATUS_PARTIAL 8 -#define BRCMF_E_STATUS_NEWSCAN 9 -#define BRCMF_E_STATUS_NEWASSOC 10 -#define BRCMF_E_STATUS_11HQUIET 11 -#define BRCMF_E_STATUS_SUPPRESS 12 -#define BRCMF_E_STATUS_NOCHANS 13 -#define BRCMF_E_STATUS_CS_ABORT 15 -#define BRCMF_E_STATUS_ERROR 16 - -#define BRCMF_E_REASON_INITIAL_ASSOC 0 -#define BRCMF_E_REASON_LOW_RSSI 1 -#define BRCMF_E_REASON_DEAUTH 2 -#define BRCMF_E_REASON_DISASSOC 3 -#define BRCMF_E_REASON_BCNS_LOST 4 -#define BRCMF_E_REASON_MINTXRATE 9 -#define BRCMF_E_REASON_TXFAIL 10 - -#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4 -#define BRCMF_E_REASON_FAST_ROAM_FAILED 5 -#define BRCMF_E_REASON_DIRECTED_ROAM 6 -#define BRCMF_E_REASON_TSPEC_REJECTED 7 -#define BRCMF_E_REASON_BETTER_AP 8 - -#define BRCMF_E_IF_ADD 1 -#define BRCMF_E_IF_DEL 2 -#define BRCMF_E_IF_CHANGE 3 - -#define BRCMF_E_IF_FLAG_NOIF 1 - -#define BRCMF_E_IF_ROLE_STA 0 -#define BRCMF_E_IF_ROLE_AP 1 -#define BRCMF_E_IF_ROLE_WDS 2 - /* Small, medium and maximum buffer size for dcmd */ #define BRCMF_DCMD_SMLEN 256 @@ -156,14 +115,6 @@ struct brcmf_pub { #endif }; -struct brcmf_if_event { - u8 ifidx; - u8 action; - u8 flags; - u8 bssidx; - u8 role; -}; - /* forward declarations */ struct brcmf_cfg80211_vif; struct brcmf_fws_mac_descriptor; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h index 14bc24d..51b53a7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h @@ -122,6 +122,52 @@ enum brcmf_fweh_event_code { #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 #define BRCMF_EVENT_MSG_GROUP 0x04 +/* status field values in struct brcmf_event_msg */ +#define BRCMF_E_STATUS_SUCCESS 0 +#define BRCMF_E_STATUS_FAIL 1 +#define BRCMF_E_STATUS_TIMEOUT 2 +#define BRCMF_E_STATUS_NO_NETWORKS 3 +#define BRCMF_E_STATUS_ABORT 4 +#define BRCMF_E_STATUS_NO_ACK 5 +#define BRCMF_E_STATUS_UNSOLICITED 6 +#define BRCMF_E_STATUS_ATTEMPT 7 +#define BRCMF_E_STATUS_PARTIAL 8 +#define BRCMF_E_STATUS_NEWSCAN 9 +#define BRCMF_E_STATUS_NEWASSOC 10 +#define BRCMF_E_STATUS_11HQUIET 11 +#define BRCMF_E_STATUS_SUPPRESS 12 +#define BRCMF_E_STATUS_NOCHANS 13 +#define BRCMF_E_STATUS_CS_ABORT 15 +#define BRCMF_E_STATUS_ERROR 16 + +/* reason field values in struct brcmf_event_msg */ +#define BRCMF_E_REASON_INITIAL_ASSOC 0 +#define BRCMF_E_REASON_LOW_RSSI 1 +#define BRCMF_E_REASON_DEAUTH 2 +#define BRCMF_E_REASON_DISASSOC 3 +#define BRCMF_E_REASON_BCNS_LOST 4 +#define BRCMF_E_REASON_MINTXRATE 9 +#define BRCMF_E_REASON_TXFAIL 10 + +#define BRCMF_E_REASON_LINK_BSSCFG_DIS 4 +#define BRCMF_E_REASON_FAST_ROAM_FAILED 5 +#define BRCMF_E_REASON_DIRECTED_ROAM 6 +#define BRCMF_E_REASON_TSPEC_REJECTED 7 +#define BRCMF_E_REASON_BETTER_AP 8 + +/* action field values for brcmf_ifevent */ +#define BRCMF_E_IF_ADD 1 +#define BRCMF_E_IF_DEL 2 +#define BRCMF_E_IF_CHANGE 3 + +/* flag field values for brcmf_ifevent */ +#define BRCMF_E_IF_FLAG_NOIF 1 + +/* role field values for brcmf_ifevent */ +#define BRCMF_E_IF_ROLE_STA 0 +#define BRCMF_E_IF_ROLE_AP 1 +#define BRCMF_E_IF_ROLE_WDS 2 + /** * definitions for event packet validation. */ @@ -160,6 +206,14 @@ struct brcmf_event_msg { u8 bsscfgidx; }; +struct brcmf_if_event { + u8 ifidx; + u8 action; + u8 flags; + u8 bssidx; + u8 role; +}; + typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, const struct brcmf_event_msg *evtmsg, void *data); -- cgit v1.1 From 7d68849f40cd9169088249cc889d95c8998c3fb8 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Fri, 29 Nov 2013 12:25:24 +0100 Subject: brcmfmac: expose chip information through debugfs Adding the debugfs file /brcmfmac//chipinfo which contains the chip number and revision. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | 36 ++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 0f9e9057..03fe8ac 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -22,7 +22,6 @@ #include "dhd.h" #include "dhd_bus.h" #include "dhd_dbg.h" -#include "tracepoint.h" static struct dentry *root_folder; @@ -42,6 +41,40 @@ void brcmf_debugfs_exit(void) root_folder = NULL; } +static +ssize_t brcmf_debugfs_chipinfo_read(struct file *f, char __user *data, + size_t count, loff_t *ppos) +{ + struct brcmf_pub *drvr = f->private_data; + struct brcmf_bus *bus = drvr->bus_if; + char buf[40]; + int res; + + /* only allow read from start */ + if (*ppos > 0) + return 0; + + res = scnprintf(buf, sizeof(buf), "chip: %x(%u) rev %u\n", + bus->chip, bus->chip, bus->chiprev); + return simple_read_from_buffer(data, count, ppos, buf, res); +} + +static const struct file_operations brcmf_debugfs_chipinfo_ops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = brcmf_debugfs_chipinfo_read +}; + +static int brcmf_debugfs_create_chipinfo(struct brcmf_pub *drvr) +{ + struct dentry *dentry = drvr->dbgfs_dir; + + if (!IS_ERR_OR_NULL(dentry)) + debugfs_create_file("chipinfo", S_IRUGO, dentry, drvr, + &brcmf_debugfs_chipinfo_ops); + return 0; +} + int brcmf_debugfs_attach(struct brcmf_pub *drvr) { struct device *dev = drvr->bus_if->dev; @@ -50,6 +83,7 @@ int brcmf_debugfs_attach(struct brcmf_pub *drvr) return -ENODEV; drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder); + brcmf_debugfs_create_chipinfo(drvr); return PTR_ERR_OR_ZERO(drvr->dbgfs_dir); } -- cgit v1.1 From 4d5504ec54d8f890e850cc6c29ee4a0e740e5a47 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:49 +0100 Subject: brcmfmac: add missing curly braces in brcmf_fws_txstatus_suppressed() The 0-day testing from Fenguang Wu issued the following warning: tree: git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next.git master head: 4b074b07625f603d40d4d04937f8874a00415dc4 commit: 1e86d69662d7d86360624f74bbe1b5fa1b8ffb13 [33/59] brcmfmac: Update fwsignal to fix out of order tx. >> drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c:1393:2-56: code aligned with following code on line 1394 vim +1393 drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c 84bcc0c3 1387 } 84bcc0c3 1388 84bcc0c3 1389 entry->generation = genbit; 84bcc0c3 1390 2747e5f7 1391 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); 2747e5f7 1392 if (ret == 0) 1e86d696 @1393 brcmf_skb_htod_tag_set_field(skb, GENERATION, .. 1e86d696 @1394 brcmf_skbcb(skb)->htod_seq = seq; 1e86d696 1395 if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) { 1e86d696 1396 brcmf_skb_htod_seq_set_field(skb, .. 1e86d696 1397 brcmf_skb_htod_seq_set_field(skb, .. This warning is valid and the if statement needs curly braces here. Reported-by: Fengguang Wu Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index e9bdfdb..a593784 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -1393,7 +1393,7 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, entry->generation = genbit; ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); - if (ret == 0) + if (ret == 0) { brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit); brcmf_skbcb(skb)->htod_seq = seq; if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) { @@ -1404,6 +1404,8 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, } ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb); + } + if (ret != 0) { /* suppress q is full or hdrpull failed, drop this packet */ brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, -- cgit v1.1 From e2dc9eea531ec90f50968d2cef2ba91b4869f250 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:50 +0100 Subject: brcmfmac: combine bcmsdh source files into one The driver has four files specific to SDIO host interface handling. This commit reduces that by merging two closely related source files. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 1 - drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 521 +++++++++++++++++++ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 552 --------------------- 3 files changed, 521 insertions(+), 553 deletions(-) delete mode 100644 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 2082402..5681b98 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -36,7 +36,6 @@ brcmfmac-objs += \ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ dhd_sdio.o \ bcmsdh.o \ - bcmsdh_sdmmc.o \ sdio_chip.o brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ usb.o diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 91651ec..d7696d3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -23,9 +23,17 @@ #include #include #include +#include #include +#include #include +#include +#include #include +#include +#include +#include +#include #include #include @@ -35,6 +43,7 @@ #include "dhd_bus.h" #include "dhd_dbg.h" #include "sdio_host.h" +#include "sdio_chip.h" #define SDIOH_API_ACCESS_RETRY_LIMIT 2 @@ -797,3 +806,515 @@ void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) else brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); } + +#define SDIO_VENDOR_ID_BROADCOM 0x02d0 + +#define DMA_ALIGN_MASK 0x03 + +#define SDIO_FUNC1_BLOCKSIZE 64 +#define SDIO_FUNC2_BLOCKSIZE 512 + +/* devices we support, null terminated */ +static const struct sdio_device_id brcmf_sdmmc_ids[] = { + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, + SDIO_DEVICE_ID_BROADCOM_4335_4339)}, + { /* end: all zeroes */ }, +}; +MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); + +static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; + + +bool +brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) +{ + bool is_err = false; +#ifdef CONFIG_PM_SLEEP + is_err = atomic_read(&sdiodev->suspend); +#endif + return is_err; +} + +void +brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq) +{ +#ifdef CONFIG_PM_SLEEP + int retry = 0; + while (atomic_read(&sdiodev->suspend) && retry++ != 30) + wait_event_timeout(*wq, false, HZ/100); +#endif +} + +static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, + uint regaddr, u8 *byte) +{ + struct sdio_func *sdfunc = sdiodev->func[0]; + int err_ret; + + /* + * Can only directly write to some F0 registers. + * Handle F2 enable/disable and Abort command + * as a special case. + */ + if (regaddr == SDIO_CCCR_IOEx) { + sdfunc = sdiodev->func[2]; + if (sdfunc) { + if (*byte & SDIO_FUNC_ENABLE_2) { + /* Enable Function 2 */ + err_ret = sdio_enable_func(sdfunc); + if (err_ret) + brcmf_err("enable F2 failed:%d\n", + err_ret); + } else { + /* Disable Function 2 */ + err_ret = sdio_disable_func(sdfunc); + if (err_ret) + brcmf_err("Disable F2 failed:%d\n", + err_ret); + } + } else { + err_ret = -ENOENT; + } + } else if ((regaddr == SDIO_CCCR_ABORT) || + (regaddr == SDIO_CCCR_IENx)) { + sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), + GFP_KERNEL); + if (!sdfunc) + return -ENOMEM; + sdfunc->num = 0; + sdio_writeb(sdfunc, *byte, regaddr, &err_ret); + kfree(sdfunc); + } else if (regaddr < 0xF0) { + brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr); + err_ret = -EPERM; + } else { + sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); + } + + return err_ret; +} + +int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, + uint regaddr, u8 *byte) +{ + int err_ret; + + brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); + + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); + if (brcmf_pm_resume_error(sdiodev)) + return -EIO; + + if (rw && func == 0) { + /* handle F0 separately */ + err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte); + } else { + if (rw) /* CMD52 Write */ + sdio_writeb(sdiodev->func[func], *byte, regaddr, + &err_ret); + else if (func == 0) { + *byte = sdio_f0_readb(sdiodev->func[func], regaddr, + &err_ret); + } else { + *byte = sdio_readb(sdiodev->func[func], regaddr, + &err_ret); + } + } + + if (err_ret) { + /* + * SleepCSR register access can fail when + * waking up the device so reduce this noise + * in the logs. + */ + if (regaddr != SBSDIO_FUNC1_SLEEPCSR) + brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "write" : "read", func, regaddr, *byte, + err_ret); + else + brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "write" : "read", func, regaddr, *byte, + err_ret); + } + return err_ret; +} + +int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, + uint rw, uint func, uint addr, u32 *word, + uint nbytes) +{ + int err_ret = -EIO; + + if (func == 0) { + brcmf_err("Only CMD52 allowed to F0\n"); + return -EINVAL; + } + + brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", + rw, func, addr, nbytes); + + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); + if (brcmf_pm_resume_error(sdiodev)) + return -EIO; + + if (rw) { /* CMD52 Write */ + if (nbytes == 4) + sdio_writel(sdiodev->func[func], *word, addr, + &err_ret); + else if (nbytes == 2) + sdio_writew(sdiodev->func[func], (*word & 0xFFFF), + addr, &err_ret); + else + brcmf_err("Invalid nbytes: %d\n", nbytes); + } else { /* CMD52 Read */ + if (nbytes == 4) + *word = sdio_readl(sdiodev->func[func], addr, &err_ret); + else if (nbytes == 2) + *word = sdio_readw(sdiodev->func[func], addr, + &err_ret) & 0xFFFF; + else + brcmf_err("Invalid nbytes: %d\n", nbytes); + } + + if (err_ret) + brcmf_err("Failed to %s word, Err: 0x%08x\n", + rw ? "write" : "read", err_ret); + + return err_ret; +} + +static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) +{ + /* read 24 bits and return valid 17 bit addr */ + int i, ret; + u32 scratch, regdata; + __le32 scratch_le; + u8 *ptr = (u8 *)&scratch_le; + + for (i = 0; i < 3; i++) { + regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret); + if (ret != 0) + brcmf_err("Can't read!\n"); + + *ptr++ = (u8) regdata; + regaddr++; + } + + /* Only the lower 17-bits are valid */ + scratch = le32_to_cpu(scratch_le); + scratch &= 0x0001FFFF; + return scratch; +} + +static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) +{ + int err_ret; + u32 fbraddr; + u8 func; + + brcmf_dbg(SDIO, "\n"); + + /* Get the Card's common CIS address */ + sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev, + SDIO_CCCR_CIS); + brcmf_dbg(SDIO, "Card's Common CIS Ptr = 0x%x\n", + sdiodev->func_cis_ptr[0]); + + /* Get the Card's function CIS (for each function) */ + for (fbraddr = SDIO_FBR_BASE(1), func = 1; + func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { + sdiodev->func_cis_ptr[func] = + brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr); + brcmf_dbg(SDIO, "Function %d CIS Ptr = 0x%x\n", + func, sdiodev->func_cis_ptr[func]); + } + + /* Enable Function 1 */ + err_ret = sdio_enable_func(sdiodev->func[1]); + if (err_ret) + brcmf_err("Failed to enable F1 Err: 0x%08x\n", err_ret); + + return false; +} + +/* + * Public entry points & extern's + */ +int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) +{ + int err_ret = 0; + struct mmc_host *host; + struct sdio_func *func; + uint max_blocks; + + brcmf_dbg(SDIO, "\n"); + + sdiodev->num_funcs = 2; + + sdio_claim_host(sdiodev->func[1]); + + err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); + if (err_ret) { + brcmf_err("Failed to set F1 blocksize\n"); + goto out; + } + + err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); + if (err_ret) { + brcmf_err("Failed to set F2 blocksize\n"); + goto out; + } + + brcmf_sdioh_enablefuncs(sdiodev); + + /* + * determine host related variables after brcmf_sdio_probe() + * as func->cur_blksize is properly set and F2 init has been + * completed successfully. + */ + func = sdiodev->func[2]; + host = func->card->host; + sdiodev->sg_support = host->max_segs > 1; + max_blocks = min_t(uint, host->max_blk_count, 511u); + sdiodev->max_request_size = min_t(uint, host->max_req_size, + max_blocks * func->cur_blksize); + sdiodev->max_segment_count = min_t(uint, host->max_segs, + SG_MAX_SINGLE_ALLOC); + sdiodev->max_segment_size = host->max_seg_size; +out: + sdio_release_host(sdiodev->func[1]); + brcmf_dbg(SDIO, "Done\n"); + return err_ret; +} + +void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) +{ + brcmf_dbg(SDIO, "\n"); + + /* Disable Function 2 */ + sdio_claim_host(sdiodev->func[2]); + sdio_disable_func(sdiodev->func[2]); + sdio_release_host(sdiodev->func[2]); + + /* Disable Function 1 */ + sdio_claim_host(sdiodev->func[1]); + sdio_disable_func(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); + +} + +static int brcmf_ops_sdio_probe(struct sdio_func *func, + const struct sdio_device_id *id) +{ + int err; + struct brcmf_sdio_dev *sdiodev; + struct brcmf_bus *bus_if; + + brcmf_dbg(SDIO, "Enter\n"); + brcmf_dbg(SDIO, "Class=%x\n", func->class); + brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor); + brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); + brcmf_dbg(SDIO, "Function#: %d\n", func->num); + + /* Consume func num 1 but dont do anything with it. */ + if (func->num == 1) + return 0; + + /* Ignore anything but func 2 */ + if (func->num != 2) + return -ENODEV; + + bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); + if (!bus_if) + return -ENOMEM; + sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); + if (!sdiodev) { + kfree(bus_if); + return -ENOMEM; + } + + sdiodev->func[0] = func->card->sdio_func[0]; + sdiodev->func[1] = func->card->sdio_func[0]; + sdiodev->func[2] = func; + + sdiodev->bus_if = bus_if; + bus_if->bus_priv.sdio = sdiodev; + dev_set_drvdata(&func->dev, bus_if); + dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); + sdiodev->dev = &sdiodev->func[1]->dev; + sdiodev->pdata = brcmfmac_sdio_pdata; + + atomic_set(&sdiodev->suspend, false); + init_waitqueue_head(&sdiodev->request_byte_wait); + init_waitqueue_head(&sdiodev->request_word_wait); + init_waitqueue_head(&sdiodev->request_buffer_wait); + + brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); + err = brcmf_sdio_probe(sdiodev); + if (err) { + brcmf_err("F2 error, probe failed %d...\n", err); + goto fail; + } + + brcmf_dbg(SDIO, "F2 init completed...\n"); + return 0; + +fail: + dev_set_drvdata(&func->dev, NULL); + dev_set_drvdata(&sdiodev->func[1]->dev, NULL); + kfree(sdiodev); + kfree(bus_if); + return err; +} + +static void brcmf_ops_sdio_remove(struct sdio_func *func) +{ + struct brcmf_bus *bus_if; + struct brcmf_sdio_dev *sdiodev; + + brcmf_dbg(SDIO, "Enter\n"); + brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor); + brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); + brcmf_dbg(SDIO, "Function: %d\n", func->num); + + if (func->num != 1 && func->num != 2) + return; + + bus_if = dev_get_drvdata(&func->dev); + if (bus_if) { + sdiodev = bus_if->bus_priv.sdio; + brcmf_sdio_remove(sdiodev); + + dev_set_drvdata(&sdiodev->func[1]->dev, NULL); + dev_set_drvdata(&sdiodev->func[2]->dev, NULL); + + kfree(bus_if); + kfree(sdiodev); + } + + brcmf_dbg(SDIO, "Exit\n"); +} + +#ifdef CONFIG_PM_SLEEP +static int brcmf_sdio_suspend(struct device *dev) +{ + mmc_pm_flag_t sdio_flags; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + int ret = 0; + + brcmf_dbg(SDIO, "\n"); + + atomic_set(&sdiodev->suspend, true); + + sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]); + if (!(sdio_flags & MMC_PM_KEEP_POWER)) { + brcmf_err("Host can't keep power while suspended\n"); + return -EINVAL; + } + + ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); + if (ret) { + brcmf_err("Failed to set pm_flags\n"); + return ret; + } + + brcmf_sdio_wdtmr_enable(sdiodev, false); + + return ret; +} + +static int brcmf_sdio_resume(struct device *dev) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + + brcmf_sdio_wdtmr_enable(sdiodev, true); + atomic_set(&sdiodev->suspend, false); + return 0; +} + +static const struct dev_pm_ops brcmf_sdio_pm_ops = { + .suspend = brcmf_sdio_suspend, + .resume = brcmf_sdio_resume, +}; +#endif /* CONFIG_PM_SLEEP */ + +static struct sdio_driver brcmf_sdmmc_driver = { + .probe = brcmf_ops_sdio_probe, + .remove = brcmf_ops_sdio_remove, + .name = BRCMFMAC_SDIO_PDATA_NAME, + .id_table = brcmf_sdmmc_ids, +#ifdef CONFIG_PM_SLEEP + .drv = { + .pm = &brcmf_sdio_pm_ops, + }, +#endif /* CONFIG_PM_SLEEP */ +}; + +static int brcmf_sdio_pd_probe(struct platform_device *pdev) +{ + brcmf_dbg(SDIO, "Enter\n"); + + brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); + + if (brcmfmac_sdio_pdata->power_on) + brcmfmac_sdio_pdata->power_on(); + + return 0; +} + +static int brcmf_sdio_pd_remove(struct platform_device *pdev) +{ + brcmf_dbg(SDIO, "Enter\n"); + + if (brcmfmac_sdio_pdata->power_off) + brcmfmac_sdio_pdata->power_off(); + + sdio_unregister_driver(&brcmf_sdmmc_driver); + + return 0; +} + +static struct platform_driver brcmf_sdio_pd = { + .remove = brcmf_sdio_pd_remove, + .driver = { + .name = BRCMFMAC_SDIO_PDATA_NAME, + .owner = THIS_MODULE, + } +}; + +void brcmf_sdio_register(void) +{ + int ret; + + ret = sdio_register_driver(&brcmf_sdmmc_driver); + if (ret) + brcmf_err("sdio_register_driver failed: %d\n", ret); +} + +void brcmf_sdio_exit(void) +{ + brcmf_dbg(SDIO, "Enter\n"); + + if (brcmfmac_sdio_pdata) + platform_driver_unregister(&brcmf_sdio_pd); + else + sdio_unregister_driver(&brcmf_sdmmc_driver); +} + +void __init brcmf_sdio_init(void) +{ + int ret; + + brcmf_dbg(SDIO, "Enter\n"); + + ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); + if (ret == -ENODEV) + brcmf_dbg(SDIO, "No platform data available.\n"); +} diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c deleted file mode 100644 index a511c27..0000000 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* request_irq() */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include "sdio_host.h" -#include "sdio_chip.h" -#include "dhd_dbg.h" -#include "dhd_bus.h" - -#define SDIO_VENDOR_ID_BROADCOM 0x02d0 - -#define DMA_ALIGN_MASK 0x03 - -#define SDIO_FUNC1_BLOCKSIZE 64 -#define SDIO_FUNC2_BLOCKSIZE 512 - -/* devices we support, null terminated */ -static const struct sdio_device_id brcmf_sdmmc_ids[] = { - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, - SDIO_DEVICE_ID_BROADCOM_4335_4339)}, - { /* end: all zeroes */ }, -}; -MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); - -static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; - - -bool -brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) -{ - bool is_err = false; -#ifdef CONFIG_PM_SLEEP - is_err = atomic_read(&sdiodev->suspend); -#endif - return is_err; -} - -void -brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq) -{ -#ifdef CONFIG_PM_SLEEP - int retry = 0; - while (atomic_read(&sdiodev->suspend) && retry++ != 30) - wait_event_timeout(*wq, false, HZ/100); -#endif -} - -static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, - uint regaddr, u8 *byte) -{ - struct sdio_func *sdfunc = sdiodev->func[0]; - int err_ret; - - /* - * Can only directly write to some F0 registers. - * Handle F2 enable/disable and Abort command - * as a special case. - */ - if (regaddr == SDIO_CCCR_IOEx) { - sdfunc = sdiodev->func[2]; - if (sdfunc) { - if (*byte & SDIO_FUNC_ENABLE_2) { - /* Enable Function 2 */ - err_ret = sdio_enable_func(sdfunc); - if (err_ret) - brcmf_err("enable F2 failed:%d\n", - err_ret); - } else { - /* Disable Function 2 */ - err_ret = sdio_disable_func(sdfunc); - if (err_ret) - brcmf_err("Disable F2 failed:%d\n", - err_ret); - } - } else { - err_ret = -ENOENT; - } - } else if ((regaddr == SDIO_CCCR_ABORT) || - (regaddr == SDIO_CCCR_IENx)) { - sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), - GFP_KERNEL); - if (!sdfunc) - return -ENOMEM; - sdfunc->num = 0; - sdio_writeb(sdfunc, *byte, regaddr, &err_ret); - kfree(sdfunc); - } else if (regaddr < 0xF0) { - brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr); - err_ret = -EPERM; - } else { - sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); - } - - return err_ret; -} - -int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, - uint regaddr, u8 *byte) -{ - int err_ret; - - brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); - - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); - if (brcmf_pm_resume_error(sdiodev)) - return -EIO; - - if (rw && func == 0) { - /* handle F0 separately */ - err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte); - } else { - if (rw) /* CMD52 Write */ - sdio_writeb(sdiodev->func[func], *byte, regaddr, - &err_ret); - else if (func == 0) { - *byte = sdio_f0_readb(sdiodev->func[func], regaddr, - &err_ret); - } else { - *byte = sdio_readb(sdiodev->func[func], regaddr, - &err_ret); - } - } - - if (err_ret) { - /* - * SleepCSR register access can fail when - * waking up the device so reduce this noise - * in the logs. - */ - if (regaddr != SBSDIO_FUNC1_SLEEPCSR) - brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "write" : "read", func, regaddr, *byte, - err_ret); - else - brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "write" : "read", func, regaddr, *byte, - err_ret); - } - return err_ret; -} - -int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, - uint rw, uint func, uint addr, u32 *word, - uint nbytes) -{ - int err_ret = -EIO; - - if (func == 0) { - brcmf_err("Only CMD52 allowed to F0\n"); - return -EINVAL; - } - - brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - rw, func, addr, nbytes); - - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); - if (brcmf_pm_resume_error(sdiodev)) - return -EIO; - - if (rw) { /* CMD52 Write */ - if (nbytes == 4) - sdio_writel(sdiodev->func[func], *word, addr, - &err_ret); - else if (nbytes == 2) - sdio_writew(sdiodev->func[func], (*word & 0xFFFF), - addr, &err_ret); - else - brcmf_err("Invalid nbytes: %d\n", nbytes); - } else { /* CMD52 Read */ - if (nbytes == 4) - *word = sdio_readl(sdiodev->func[func], addr, &err_ret); - else if (nbytes == 2) - *word = sdio_readw(sdiodev->func[func], addr, - &err_ret) & 0xFFFF; - else - brcmf_err("Invalid nbytes: %d\n", nbytes); - } - - if (err_ret) - brcmf_err("Failed to %s word, Err: 0x%08x\n", - rw ? "write" : "read", err_ret); - - return err_ret; -} - -static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) -{ - /* read 24 bits and return valid 17 bit addr */ - int i, ret; - u32 scratch, regdata; - __le32 scratch_le; - u8 *ptr = (u8 *)&scratch_le; - - for (i = 0; i < 3; i++) { - regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret); - if (ret != 0) - brcmf_err("Can't read!\n"); - - *ptr++ = (u8) regdata; - regaddr++; - } - - /* Only the lower 17-bits are valid */ - scratch = le32_to_cpu(scratch_le); - scratch &= 0x0001FFFF; - return scratch; -} - -static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) -{ - int err_ret; - u32 fbraddr; - u8 func; - - brcmf_dbg(SDIO, "\n"); - - /* Get the Card's common CIS address */ - sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev, - SDIO_CCCR_CIS); - brcmf_dbg(SDIO, "Card's Common CIS Ptr = 0x%x\n", - sdiodev->func_cis_ptr[0]); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIO_FBR_BASE(1), func = 1; - func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sdiodev->func_cis_ptr[func] = - brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr); - brcmf_dbg(SDIO, "Function %d CIS Ptr = 0x%x\n", - func, sdiodev->func_cis_ptr[func]); - } - - /* Enable Function 1 */ - err_ret = sdio_enable_func(sdiodev->func[1]); - if (err_ret) - brcmf_err("Failed to enable F1 Err: 0x%08x\n", err_ret); - - return false; -} - -/* - * Public entry points & extern's - */ -int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) -{ - int err_ret = 0; - struct mmc_host *host; - struct sdio_func *func; - uint max_blocks; - - brcmf_dbg(SDIO, "\n"); - - sdiodev->num_funcs = 2; - - sdio_claim_host(sdiodev->func[1]); - - err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); - if (err_ret) { - brcmf_err("Failed to set F1 blocksize\n"); - goto out; - } - - err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); - if (err_ret) { - brcmf_err("Failed to set F2 blocksize\n"); - goto out; - } - - brcmf_sdioh_enablefuncs(sdiodev); - - /* - * determine host related variables after brcmf_sdio_probe() - * as func->cur_blksize is properly set and F2 init has been - * completed successfully. - */ - func = sdiodev->func[2]; - host = func->card->host; - sdiodev->sg_support = host->max_segs > 1; - max_blocks = min_t(uint, host->max_blk_count, 511u); - sdiodev->max_request_size = min_t(uint, host->max_req_size, - max_blocks * func->cur_blksize); - sdiodev->max_segment_count = min_t(uint, host->max_segs, - SG_MAX_SINGLE_ALLOC); - sdiodev->max_segment_size = host->max_seg_size; -out: - sdio_release_host(sdiodev->func[1]); - brcmf_dbg(SDIO, "Done\n"); - return err_ret; -} - -void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) -{ - brcmf_dbg(SDIO, "\n"); - - /* Disable Function 2 */ - sdio_claim_host(sdiodev->func[2]); - sdio_disable_func(sdiodev->func[2]); - sdio_release_host(sdiodev->func[2]); - - /* Disable Function 1 */ - sdio_claim_host(sdiodev->func[1]); - sdio_disable_func(sdiodev->func[1]); - sdio_release_host(sdiodev->func[1]); - -} - -static int brcmf_ops_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int err; - struct brcmf_sdio_dev *sdiodev; - struct brcmf_bus *bus_if; - - brcmf_dbg(SDIO, "Enter\n"); - brcmf_dbg(SDIO, "Class=%x\n", func->class); - brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor); - brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(SDIO, "Function#: %d\n", func->num); - - /* Consume func num 1 but dont do anything with it. */ - if (func->num == 1) - return 0; - - /* Ignore anything but func 2 */ - if (func->num != 2) - return -ENODEV; - - bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); - if (!bus_if) - return -ENOMEM; - sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); - if (!sdiodev) { - kfree(bus_if); - return -ENOMEM; - } - - sdiodev->func[0] = func->card->sdio_func[0]; - sdiodev->func[1] = func->card->sdio_func[0]; - sdiodev->func[2] = func; - - sdiodev->bus_if = bus_if; - bus_if->bus_priv.sdio = sdiodev; - dev_set_drvdata(&func->dev, bus_if); - dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); - sdiodev->dev = &sdiodev->func[1]->dev; - sdiodev->pdata = brcmfmac_sdio_pdata; - - atomic_set(&sdiodev->suspend, false); - init_waitqueue_head(&sdiodev->request_byte_wait); - init_waitqueue_head(&sdiodev->request_word_wait); - init_waitqueue_head(&sdiodev->request_buffer_wait); - - brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); - err = brcmf_sdio_probe(sdiodev); - if (err) { - brcmf_err("F2 error, probe failed %d...\n", err); - goto fail; - } - - brcmf_dbg(SDIO, "F2 init completed...\n"); - return 0; - -fail: - dev_set_drvdata(&func->dev, NULL); - dev_set_drvdata(&sdiodev->func[1]->dev, NULL); - kfree(sdiodev); - kfree(bus_if); - return err; -} - -static void brcmf_ops_sdio_remove(struct sdio_func *func) -{ - struct brcmf_bus *bus_if; - struct brcmf_sdio_dev *sdiodev; - - brcmf_dbg(SDIO, "Enter\n"); - brcmf_dbg(SDIO, "sdio vendor ID: 0x%04x\n", func->vendor); - brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(SDIO, "Function: %d\n", func->num); - - if (func->num != 1 && func->num != 2) - return; - - bus_if = dev_get_drvdata(&func->dev); - if (bus_if) { - sdiodev = bus_if->bus_priv.sdio; - brcmf_sdio_remove(sdiodev); - - dev_set_drvdata(&sdiodev->func[1]->dev, NULL); - dev_set_drvdata(&sdiodev->func[2]->dev, NULL); - - kfree(bus_if); - kfree(sdiodev); - } - - brcmf_dbg(SDIO, "Exit\n"); -} - -#ifdef CONFIG_PM_SLEEP -static int brcmf_sdio_suspend(struct device *dev) -{ - mmc_pm_flag_t sdio_flags; - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - int ret = 0; - - brcmf_dbg(SDIO, "\n"); - - atomic_set(&sdiodev->suspend, true); - - sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]); - if (!(sdio_flags & MMC_PM_KEEP_POWER)) { - brcmf_err("Host can't keep power while suspended\n"); - return -EINVAL; - } - - ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); - if (ret) { - brcmf_err("Failed to set pm_flags\n"); - return ret; - } - - brcmf_sdio_wdtmr_enable(sdiodev, false); - - return ret; -} - -static int brcmf_sdio_resume(struct device *dev) -{ - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - - brcmf_sdio_wdtmr_enable(sdiodev, true); - atomic_set(&sdiodev->suspend, false); - return 0; -} - -static const struct dev_pm_ops brcmf_sdio_pm_ops = { - .suspend = brcmf_sdio_suspend, - .resume = brcmf_sdio_resume, -}; -#endif /* CONFIG_PM_SLEEP */ - -static struct sdio_driver brcmf_sdmmc_driver = { - .probe = brcmf_ops_sdio_probe, - .remove = brcmf_ops_sdio_remove, - .name = BRCMFMAC_SDIO_PDATA_NAME, - .id_table = brcmf_sdmmc_ids, -#ifdef CONFIG_PM_SLEEP - .drv = { - .pm = &brcmf_sdio_pm_ops, - }, -#endif /* CONFIG_PM_SLEEP */ -}; - -static int brcmf_sdio_pd_probe(struct platform_device *pdev) -{ - brcmf_dbg(SDIO, "Enter\n"); - - brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); - - if (brcmfmac_sdio_pdata->power_on) - brcmfmac_sdio_pdata->power_on(); - - return 0; -} - -static int brcmf_sdio_pd_remove(struct platform_device *pdev) -{ - brcmf_dbg(SDIO, "Enter\n"); - - if (brcmfmac_sdio_pdata->power_off) - brcmfmac_sdio_pdata->power_off(); - - sdio_unregister_driver(&brcmf_sdmmc_driver); - - return 0; -} - -static struct platform_driver brcmf_sdio_pd = { - .remove = brcmf_sdio_pd_remove, - .driver = { - .name = BRCMFMAC_SDIO_PDATA_NAME, - .owner = THIS_MODULE, - } -}; - -void brcmf_sdio_register(void) -{ - int ret; - - ret = sdio_register_driver(&brcmf_sdmmc_driver); - if (ret) - brcmf_err("sdio_register_driver failed: %d\n", ret); -} - -void brcmf_sdio_exit(void) -{ - brcmf_dbg(SDIO, "Enter\n"); - - if (brcmfmac_sdio_pdata) - platform_driver_unregister(&brcmf_sdio_pd); - else - sdio_unregister_driver(&brcmf_sdmmc_driver); -} - -void __init brcmf_sdio_init(void) -{ - int ret; - - brcmf_dbg(SDIO, "Enter\n"); - - ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); - if (ret == -ENODEV) - brcmf_dbg(SDIO, "No platform data available.\n"); -} -- cgit v1.1 From e49b06ba6610e15e0173b99c2830315d814d1725 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:51 +0100 Subject: brcmfmac: remove unnecessary function prototypes With the merge of bcmsdh.c and bcmsdh_mmc.c several function prototypes are no longer necessary and can be removed. Consequence is reordering some of the functions. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 467 ++++++++++----------- .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 27 -- 2 files changed, 231 insertions(+), 263 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index d7696d3..c9b3f8c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -47,6 +47,12 @@ #define SDIOH_API_ACCESS_RETRY_LIMIT 2 +#define SDIO_VENDOR_ID_BROADCOM 0x02d0 + +#define DMA_ALIGN_MASK 0x03 + +#define SDIO_FUNC1_BLOCKSIZE 64 +#define SDIO_FUNC2_BLOCKSIZE 512 static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id) { @@ -83,6 +89,25 @@ static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func) { } +static bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) +{ + bool is_err = false; +#ifdef CONFIG_PM_SLEEP + is_err = atomic_read(&sdiodev->suspend); +#endif + return is_err; +} + +static void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, + wait_queue_head_t *wq) +{ +#ifdef CONFIG_PM_SLEEP + int retry = 0; + while (atomic_read(&sdiodev->suspend) && retry++ != 30) + wait_event_timeout(*wq, false, HZ/100); +#endif +} + int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) { int ret = 0; @@ -169,6 +194,144 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) return 0; } +static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, + uint regaddr, u8 *byte) +{ + struct sdio_func *sdfunc = sdiodev->func[0]; + int err_ret; + + /* + * Can only directly write to some F0 registers. + * Handle F2 enable/disable and Abort command + * as a special case. + */ + if (regaddr == SDIO_CCCR_IOEx) { + sdfunc = sdiodev->func[2]; + if (sdfunc) { + if (*byte & SDIO_FUNC_ENABLE_2) { + /* Enable Function 2 */ + err_ret = sdio_enable_func(sdfunc); + if (err_ret) + brcmf_err("enable F2 failed:%d\n", + err_ret); + } else { + /* Disable Function 2 */ + err_ret = sdio_disable_func(sdfunc); + if (err_ret) + brcmf_err("Disable F2 failed:%d\n", + err_ret); + } + } else { + err_ret = -ENOENT; + } + } else if ((regaddr == SDIO_CCCR_ABORT) || + (regaddr == SDIO_CCCR_IENx)) { + sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), + GFP_KERNEL); + if (!sdfunc) + return -ENOMEM; + sdfunc->num = 0; + sdio_writeb(sdfunc, *byte, regaddr, &err_ret); + kfree(sdfunc); + } else if (regaddr < 0xF0) { + brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr); + err_ret = -EPERM; + } else { + sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); + } + + return err_ret; +} + +static int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, + uint func, uint regaddr, u8 *byte) +{ + int err_ret; + + brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); + + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); + if (brcmf_pm_resume_error(sdiodev)) + return -EIO; + + if (rw && func == 0) { + /* handle F0 separately */ + err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte); + } else { + if (rw) /* CMD52 Write */ + sdio_writeb(sdiodev->func[func], *byte, regaddr, + &err_ret); + else if (func == 0) { + *byte = sdio_f0_readb(sdiodev->func[func], regaddr, + &err_ret); + } else { + *byte = sdio_readb(sdiodev->func[func], regaddr, + &err_ret); + } + } + + if (err_ret) { + /* + * SleepCSR register access can fail when + * waking up the device so reduce this noise + * in the logs. + */ + if (regaddr != SBSDIO_FUNC1_SLEEPCSR) + brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "write" : "read", func, regaddr, *byte, + err_ret); + else + brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "write" : "read", func, regaddr, *byte, + err_ret); + } + return err_ret; +} + +static int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, + uint func, uint addr, u32 *word, + uint nbytes) +{ + int err_ret = -EIO; + + if (func == 0) { + brcmf_err("Only CMD52 allowed to F0\n"); + return -EINVAL; + } + + brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", + rw, func, addr, nbytes); + + brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); + if (brcmf_pm_resume_error(sdiodev)) + return -EIO; + + if (rw) { /* CMD52 Write */ + if (nbytes == 4) + sdio_writel(sdiodev->func[func], *word, addr, + &err_ret); + else if (nbytes == 2) + sdio_writew(sdiodev->func[func], (*word & 0xFFFF), + addr, &err_ret); + else + brcmf_err("Invalid nbytes: %d\n", nbytes); + } else { /* CMD52 Read */ + if (nbytes == 4) + *word = sdio_readl(sdiodev->func[func], addr, &err_ret); + else if (nbytes == 2) + *word = sdio_readw(sdiodev->func[func], addr, + &err_ret) & 0xFFFF; + else + brcmf_err("Invalid nbytes: %d\n", nbytes); + } + + if (err_ret) + brcmf_err("Failed to %s word, Err: 0x%08x\n", + rw ? "write" : "read", err_ret); + + return err_ret; +} + static int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) { @@ -757,237 +920,6 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) return 0; } -int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) -{ - u32 regs = 0; - int ret = 0; - - ret = brcmf_sdioh_attach(sdiodev); - if (ret) - goto out; - - regs = SI_ENUM_BASE; - - /* try to attach to the target device */ - sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); - if (!sdiodev->bus) { - brcmf_err("device attach failed\n"); - ret = -ENODEV; - goto out; - } - -out: - if (ret) - brcmf_sdio_remove(sdiodev); - - return ret; -} - -int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) -{ - sdiodev->bus_if->state = BRCMF_BUS_DOWN; - - if (sdiodev->bus) { - brcmf_sdbrcm_disconnect(sdiodev->bus); - sdiodev->bus = NULL; - } - - brcmf_sdioh_detach(sdiodev); - - sdiodev->sbwad = 0; - - return 0; -} - -void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) -{ - if (enable) - brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); - else - brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); -} - -#define SDIO_VENDOR_ID_BROADCOM 0x02d0 - -#define DMA_ALIGN_MASK 0x03 - -#define SDIO_FUNC1_BLOCKSIZE 64 -#define SDIO_FUNC2_BLOCKSIZE 512 - -/* devices we support, null terminated */ -static const struct sdio_device_id brcmf_sdmmc_ids[] = { - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, - SDIO_DEVICE_ID_BROADCOM_4335_4339)}, - { /* end: all zeroes */ }, -}; -MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); - -static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; - - -bool -brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) -{ - bool is_err = false; -#ifdef CONFIG_PM_SLEEP - is_err = atomic_read(&sdiodev->suspend); -#endif - return is_err; -} - -void -brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq) -{ -#ifdef CONFIG_PM_SLEEP - int retry = 0; - while (atomic_read(&sdiodev->suspend) && retry++ != 30) - wait_event_timeout(*wq, false, HZ/100); -#endif -} - -static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, - uint regaddr, u8 *byte) -{ - struct sdio_func *sdfunc = sdiodev->func[0]; - int err_ret; - - /* - * Can only directly write to some F0 registers. - * Handle F2 enable/disable and Abort command - * as a special case. - */ - if (regaddr == SDIO_CCCR_IOEx) { - sdfunc = sdiodev->func[2]; - if (sdfunc) { - if (*byte & SDIO_FUNC_ENABLE_2) { - /* Enable Function 2 */ - err_ret = sdio_enable_func(sdfunc); - if (err_ret) - brcmf_err("enable F2 failed:%d\n", - err_ret); - } else { - /* Disable Function 2 */ - err_ret = sdio_disable_func(sdfunc); - if (err_ret) - brcmf_err("Disable F2 failed:%d\n", - err_ret); - } - } else { - err_ret = -ENOENT; - } - } else if ((regaddr == SDIO_CCCR_ABORT) || - (regaddr == SDIO_CCCR_IENx)) { - sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), - GFP_KERNEL); - if (!sdfunc) - return -ENOMEM; - sdfunc->num = 0; - sdio_writeb(sdfunc, *byte, regaddr, &err_ret); - kfree(sdfunc); - } else if (regaddr < 0xF0) { - brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr); - err_ret = -EPERM; - } else { - sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); - } - - return err_ret; -} - -int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, - uint regaddr, u8 *byte) -{ - int err_ret; - - brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); - - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); - if (brcmf_pm_resume_error(sdiodev)) - return -EIO; - - if (rw && func == 0) { - /* handle F0 separately */ - err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte); - } else { - if (rw) /* CMD52 Write */ - sdio_writeb(sdiodev->func[func], *byte, regaddr, - &err_ret); - else if (func == 0) { - *byte = sdio_f0_readb(sdiodev->func[func], regaddr, - &err_ret); - } else { - *byte = sdio_readb(sdiodev->func[func], regaddr, - &err_ret); - } - } - - if (err_ret) { - /* - * SleepCSR register access can fail when - * waking up the device so reduce this noise - * in the logs. - */ - if (regaddr != SBSDIO_FUNC1_SLEEPCSR) - brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "write" : "read", func, regaddr, *byte, - err_ret); - else - brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "write" : "read", func, regaddr, *byte, - err_ret); - } - return err_ret; -} - -int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, - uint rw, uint func, uint addr, u32 *word, - uint nbytes) -{ - int err_ret = -EIO; - - if (func == 0) { - brcmf_err("Only CMD52 allowed to F0\n"); - return -EINVAL; - } - - brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - rw, func, addr, nbytes); - - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); - if (brcmf_pm_resume_error(sdiodev)) - return -EIO; - - if (rw) { /* CMD52 Write */ - if (nbytes == 4) - sdio_writel(sdiodev->func[func], *word, addr, - &err_ret); - else if (nbytes == 2) - sdio_writew(sdiodev->func[func], (*word & 0xFFFF), - addr, &err_ret); - else - brcmf_err("Invalid nbytes: %d\n", nbytes); - } else { /* CMD52 Read */ - if (nbytes == 4) - *word = sdio_readl(sdiodev->func[func], addr, &err_ret); - else if (nbytes == 2) - *word = sdio_readw(sdiodev->func[func], addr, - &err_ret) & 0xFFFF; - else - brcmf_err("Invalid nbytes: %d\n", nbytes); - } - - if (err_ret) - brcmf_err("Failed to %s word, Err: 0x%08x\n", - rw ? "write" : "read", err_ret); - - return err_ret; -} - static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) { /* read 24 bits and return valid 17 bit addr */ @@ -1042,10 +974,7 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) return false; } -/* - * Public entry points & extern's - */ -int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) +static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) { int err_ret = 0; struct mmc_host *host; @@ -1092,7 +1021,7 @@ out: return err_ret; } -void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) +static void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) { brcmf_dbg(SDIO, "\n"); @@ -1108,6 +1037,64 @@ void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) } +static int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) +{ + sdiodev->bus_if->state = BRCMF_BUS_DOWN; + + if (sdiodev->bus) { + brcmf_sdbrcm_disconnect(sdiodev->bus); + sdiodev->bus = NULL; + } + + brcmf_sdioh_detach(sdiodev); + + sdiodev->sbwad = 0; + + return 0; +} + +static int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) +{ + u32 regs = 0; + int ret = 0; + + ret = brcmf_sdioh_attach(sdiodev); + if (ret) + goto out; + + regs = SI_ENUM_BASE; + + /* try to attach to the target device */ + sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); + if (!sdiodev->bus) { + brcmf_err("device attach failed\n"); + ret = -ENODEV; + goto out; + } + +out: + if (ret) + brcmf_sdio_remove(sdiodev); + + return ret; +} + +/* devices we support, null terminated */ +static const struct sdio_device_id brcmf_sdmmc_ids[] = { + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43143)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, + SDIO_DEVICE_ID_BROADCOM_4335_4339)}, + { /* end: all zeroes */ }, +}; +MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); + +static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; + + static int brcmf_ops_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { @@ -1201,6 +1188,14 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) } #ifdef CONFIG_PM_SLEEP +static void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) +{ + if (enable) + brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); + else + brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); +} + static int brcmf_sdio_suspend(struct device *dev) { mmc_pm_flag_t sdio_flags; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index fc0d4f0..c1dfa97 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -236,43 +236,16 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, * nbytes: number of bytes to transfer to/from buf * Returns 0 or error code. */ -int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, - u8 *buf, uint nbytes); int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, u8 *data, uint size); /* Issue an abort to the specified function */ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); -/* platform specific/high level functions */ -int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); -int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); - -/* attach, return handler on success, NULL if failed. - * The handler shall be provided by all subsequent calls. No local cache - * cfghdl points to the starting address of pci device mapped memory - */ -int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev); -void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev); - -/* read or write one byte using cmd52 */ -int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc, - uint addr, u8 *byte); - -/* read or write 2/4 bytes using cmd53 */ -int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc, - uint addr, u32 *word, uint nbyte); - -/* Watchdog timer interface for pm ops */ -void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable); - void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); void brcmf_sdbrcm_disconnect(void *ptr); void brcmf_sdbrcm_isr(void *arg); void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); -void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, - wait_queue_head_t *wq); -bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev); #endif /* _BRCM_SDH_H_ */ -- cgit v1.1 From 463c30b3f987b9933a705227964847b49d4d7b32 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:52 +0100 Subject: brcmfmac: remove unused struct brcmf_sdio_dev::func_cis_ptr attribute During the SDIO probe the func_cis_ptr attribute in struct brcmf_sdio_dev is being determined, but it is never used after that. Removing it also obsoletes two functions in bcmsdh.c. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 61 +++------------------- .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 1 - 2 files changed, 6 insertions(+), 56 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index c9b3f8c..e5f25c5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -920,60 +920,6 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) return 0; } -static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) -{ - /* read 24 bits and return valid 17 bit addr */ - int i, ret; - u32 scratch, regdata; - __le32 scratch_le; - u8 *ptr = (u8 *)&scratch_le; - - for (i = 0; i < 3; i++) { - regdata = brcmf_sdio_regrl(sdiodev, regaddr, &ret); - if (ret != 0) - brcmf_err("Can't read!\n"); - - *ptr++ = (u8) regdata; - regaddr++; - } - - /* Only the lower 17-bits are valid */ - scratch = le32_to_cpu(scratch_le); - scratch &= 0x0001FFFF; - return scratch; -} - -static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) -{ - int err_ret; - u32 fbraddr; - u8 func; - - brcmf_dbg(SDIO, "\n"); - - /* Get the Card's common CIS address */ - sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev, - SDIO_CCCR_CIS); - brcmf_dbg(SDIO, "Card's Common CIS Ptr = 0x%x\n", - sdiodev->func_cis_ptr[0]); - - /* Get the Card's function CIS (for each function) */ - for (fbraddr = SDIO_FBR_BASE(1), func = 1; - func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sdiodev->func_cis_ptr[func] = - brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr); - brcmf_dbg(SDIO, "Function %d CIS Ptr = 0x%x\n", - func, sdiodev->func_cis_ptr[func]); - } - - /* Enable Function 1 */ - err_ret = sdio_enable_func(sdiodev->func[1]); - if (err_ret) - brcmf_err("Failed to enable F1 Err: 0x%08x\n", err_ret); - - return false; -} - static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) { int err_ret = 0; @@ -999,7 +945,12 @@ static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) goto out; } - brcmf_sdioh_enablefuncs(sdiodev); + /* Enable Function 1 */ + err_ret = sdio_enable_func(sdiodev->func[1]); + if (err_ret) { + brcmf_err("Failed to enable F1 Err: 0x%08x\n", err_ret); + goto out; + } /* * determine host related variables after brcmf_sdio_probe() diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index c1dfa97..8b8f2a9 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -164,7 +164,6 @@ struct brcmf_sdio; struct brcmf_sdio_dev { struct sdio_func *func[SDIO_MAX_FUNCS]; u8 num_funcs; /* Supported funcs on client */ - u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; u32 sbwad; /* Save backplane window address */ void *bus; atomic_t suspend; /* suspend flag */ -- cgit v1.1 From 71370eb87b4815d4cb4c901b85386b4e7b72c578 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:53 +0100 Subject: brcmfmac: use sdio functions to enable/disable F2 Instead of catching CCCR_IOEx register in F0 write access to determine whether F2 state needs to change do it with direct call to sdio_[enable/disable]_func(). Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 29 ++++++------------- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 33 ++++------------------ 2 files changed, 14 insertions(+), 48 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index e5f25c5..134bef66 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -53,6 +53,9 @@ #define SDIO_FUNC1_BLOCKSIZE 64 #define SDIO_FUNC2_BLOCKSIZE 512 +/* Maximum milliseconds to wait for F2 to come up */ +#define SDIO_WAIT_F2RDY 3000 + static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id) { @@ -205,27 +208,8 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, * Handle F2 enable/disable and Abort command * as a special case. */ - if (regaddr == SDIO_CCCR_IOEx) { - sdfunc = sdiodev->func[2]; - if (sdfunc) { - if (*byte & SDIO_FUNC_ENABLE_2) { - /* Enable Function 2 */ - err_ret = sdio_enable_func(sdfunc); - if (err_ret) - brcmf_err("enable F2 failed:%d\n", - err_ret); - } else { - /* Disable Function 2 */ - err_ret = sdio_disable_func(sdfunc); - if (err_ret) - brcmf_err("Disable F2 failed:%d\n", - err_ret); - } - } else { - err_ret = -ENOENT; - } - } else if ((regaddr == SDIO_CCCR_ABORT) || - (regaddr == SDIO_CCCR_IENx)) { + if ((regaddr == SDIO_CCCR_ABORT) || + (regaddr == SDIO_CCCR_IENx)) { sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), GFP_KERNEL); if (!sdfunc) @@ -945,6 +929,9 @@ static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) goto out; } + /* increase F2 timeout */ + sdiodev->func[2]->enable_timeout = SDIO_WAIT_F2RDY; + /* Enable Function 1 */ err_ret = sdio_enable_func(sdiodev->func[1]); if (err_ret) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 0f95f3e..c3f3d8d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -260,9 +260,6 @@ struct rte_console { #define MAX_HDR_READ (1 << 6) #define MAX_RX_DATASZ 2048 -/* Maximum milliseconds to wait for F2 to come up */ -#define BRCMF_WAIT_F2RDY 3000 - /* Bump up limit on waiting for HT to account for first startup; * if the image is doing a CRC calculation before programming the PMU * for HT availability, it could take a couple hundred ms more, so @@ -2265,8 +2262,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) /* Turn off the bus (F2), free any pending packets */ brcmf_dbg(INTR, "disable SDIO interrupts\n"); - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, - NULL); + sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); /* Clear any pending interrupts now that F2 is disabled */ w_sdreg32(bus, local_hostintmask, @@ -3570,8 +3566,6 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; - unsigned long timeout; - u8 ready, enable; int err, ret = 0; u8 saveclk; @@ -3612,26 +3606,13 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) /* Enable function 2 (frame transfers) */ w_sdreg32(bus, SDPCM_PROT_VERSION << SMB_DATA_VERSION_SHIFT, offsetof(struct sdpcmd_regs, tosbmailboxdata)); - enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); - - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL); + err = sdio_enable_func(bus->sdiodev->func[SDIO_FUNC_2]); - timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY); - ready = 0; - while (enable != ready) { - ready = brcmf_sdio_regrb(bus->sdiodev, - SDIO_CCCR_IORx, NULL); - if (time_after(jiffies, timeout)) - break; - else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50)) - /* prevent busy waiting if it takes too long */ - msleep_interruptible(20); - } - brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready); + brcmf_dbg(INFO, "enable F2: err=%d\n", err); /* If F2 successfully enabled, set core and enable interrupts */ - if (ready == enable) { + if (!err) { /* Set up the interrupt mask and enable interrupts */ bus->hostintmask = HOSTINTMASK; w_sdreg32(bus, bus->hostintmask, @@ -3640,8 +3621,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err); } else { /* Disable F2 again */ - enable = SDIO_FUNC_ENABLE_1; - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, enable, NULL); + sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); ret = -ENODEV; } @@ -3942,8 +3922,7 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) sdio_claim_host(bus->sdiodev->func[1]); /* Disable F2 to clear any intermediate frame state on the dongle */ - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, - SDIO_FUNC_ENABLE_1, NULL); + sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; bus->rxflow = false; -- cgit v1.1 From 1cee05e38479efc11f1e7178b49108369c6f059e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:54 +0100 Subject: brcmfmac: remove brcmf_sdio_regrw_helper() from header file Make brcmf_sdio_regrw_helper() static removing its use outside of the bcmsdh.c source file. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 5 ++--- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 4 ++-- drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 134bef66..3934afa 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -369,9 +369,8 @@ brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) return 0; } -int -brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - void *data, bool write) +static int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, + void *data, bool write) { u8 func_num, reg_size; s32 retry = 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index c3f3d8d..a70feb5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2316,7 +2316,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) addr = bus->ci->c_inf[idx].base + offsetof(struct sdpcmd_regs, intstatus); - ret = brcmf_sdio_regrw_helper(bus->sdiodev, addr, &val, false); + val = brcmf_sdio_regrl(bus->sdiodev, addr, &ret); bus->sdcnt.f1regdata++; if (ret != 0) val = 0; @@ -2326,7 +2326,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) /* Clear interrupts */ if (val) { - ret = brcmf_sdio_regrw_helper(bus->sdiodev, addr, &val, true); + brcmf_sdio_regwl(bus->sdiodev, addr, val, &ret); bus->sdcnt.f1regdata++; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 8b8f2a9..a1e5f72 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -194,8 +194,6 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, int *ret); void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, int *ret); -int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - void *data, bool write); /* Buffer transfer to/from device (client) core via cmd53. * fn: function number -- cgit v1.1 From 4744d16402e3557dc98359effaec3371e78a9bc3 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:55 +0100 Subject: brcmfmac: remove regs parameter from sdio probe functions The chip recognition requires a base address that was provided to it during the probe. However, the address is a fixed define value so it is unnecessary to pass through the probe functions. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 5 +---- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 11 ++++------- drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | 8 ++++---- drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | 2 +- drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | 2 +- 5 files changed, 11 insertions(+), 17 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3934afa..ec9f5ed 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -992,17 +992,14 @@ static int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) static int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) { - u32 regs = 0; int ret = 0; ret = brcmf_sdioh_attach(sdiodev); if (ret) goto out; - regs = SI_ENUM_BASE; - /* try to attach to the target device */ - sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); + sdiodev->bus = brcmf_sdbrcm_probe(sdiodev); if (!sdiodev->bus) { brcmf_err("device attach failed\n"); ret = -ENODEV; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index a70feb5..24d69f4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3803,7 +3803,7 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) } static bool -brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) +brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus) { u8 clkctl = 0; int err = 0; @@ -3835,7 +3835,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) goto fail; } - if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci, regsva)) { + if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) { brcmf_err("brcmf_sdio_chip_attach failed!\n"); goto fail; } @@ -4037,16 +4037,13 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = { .gettxq = brcmf_sdbrcm_bus_gettxq, }; -void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) +void *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_sdio *bus; brcmf_dbg(TRACE, "Enter\n"); - /* We make an assumption about address window mappings: - * regsva == SI_ENUM_BASE*/ - /* Allocate private bus interface state */ bus = kzalloc(sizeof(struct brcmf_sdio), GFP_ATOMIC); if (!bus) @@ -4080,7 +4077,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) } /* attempt to attach to the dongle */ - if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { + if (!(brcmf_sdbrcm_probe_attach(bus))) { brcmf_err("brcmf_sdbrcm_probe_attach failed\n"); goto fail; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 2096a14..b612808d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -438,7 +438,7 @@ static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) #endif static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u32 regs) + struct chip_info *ci) { u32 regdata; int ret; @@ -449,7 +449,7 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, * other ways of recognition should be added here. */ ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; - ci->c_inf[0].base = regs; + ci->c_inf[0].base = SI_ENUM_BASE; regdata = brcmf_sdio_regrl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, chipid), NULL); @@ -681,7 +681,7 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, } int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, - struct chip_info **ci_ptr, u32 regs) + struct chip_info **ci_ptr) { int ret; struct chip_info *ci; @@ -697,7 +697,7 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, if (ret != 0) goto err; - ret = brcmf_sdio_chip_recognition(sdiodev, ci, regs); + ret = brcmf_sdio_chip_recognition(sdiodev, ci); if (ret != 0) goto err; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index 507c61c..d0f4b45 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -224,7 +224,7 @@ struct sdpcmd_regs { }; int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, - struct chip_info **ci_ptr, u32 regs); + struct chip_info **ci_ptr); void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u32 drivestrength); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index a1e5f72..d98b4bd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -239,7 +239,7 @@ int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, /* Issue an abort to the specified function */ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); -void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); +void *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev); void brcmf_sdbrcm_disconnect(void *ptr); void brcmf_sdbrcm_isr(void *arg); -- cgit v1.1 From 964ec1cfeb8f30b50e341216f25e9170ac921ffe Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:56 +0100 Subject: brcmfmac: get rid of some void pointer parameters In sdio code a couple of functions use a void pointer as argument type although it should be struct brcmf_sdio. Changing the functions to have proper type checking. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 13 ++++--------- drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | 9 ++++----- 2 files changed, 8 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 24d69f4..c42d5a0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3649,10 +3649,8 @@ exit: return ret; } -void brcmf_sdbrcm_isr(void *arg) +void brcmf_sdbrcm_isr(struct brcmf_sdio *bus) { - struct brcmf_sdio *bus = (struct brcmf_sdio *) arg; - brcmf_dbg(TRACE, "Enter\n"); if (!bus) { @@ -4037,7 +4035,7 @@ static struct brcmf_bus_ops brcmf_sdio_bus_ops = { .gettxq = brcmf_sdbrcm_bus_gettxq, }; -void *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) +struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_sdio *bus; @@ -4147,14 +4145,11 @@ fail: return NULL; } -void brcmf_sdbrcm_disconnect(void *ptr) +void brcmf_sdbrcm_disconnect(struct brcmf_sdio *bus) { - struct brcmf_sdio *bus = (struct brcmf_sdio *)ptr; - brcmf_dbg(TRACE, "Enter\n"); - if (bus) - brcmf_sdbrcm_release(bus); + brcmf_sdbrcm_release(bus); brcmf_dbg(TRACE, "Disconnected\n"); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index d98b4bd..414aa16 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -165,7 +165,7 @@ struct brcmf_sdio_dev { struct sdio_func *func[SDIO_MAX_FUNCS]; u8 num_funcs; /* Supported funcs on client */ u32 sbwad; /* Save backplane window address */ - void *bus; + struct brcmf_sdio *bus; atomic_t suspend; /* suspend flag */ wait_queue_head_t request_byte_wait; wait_queue_head_t request_word_wait; @@ -239,10 +239,9 @@ int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, /* Issue an abort to the specified function */ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); -void *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev); -void brcmf_sdbrcm_disconnect(void *ptr); -void brcmf_sdbrcm_isr(void *arg); - +struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev); +void brcmf_sdbrcm_disconnect(struct brcmf_sdio *bus); +void brcmf_sdbrcm_isr(struct brcmf_sdio *bus); void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); #endif /* _BRCM_SDH_H_ */ -- cgit v1.1 From 6043033c31556786e8b7c342978f65ef5a672a1e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:57 +0100 Subject: brcmfmac: remove brcmf_sdio_wdtimer_enable() function Instead of using the brcmf_sdio_wdtimer_enable() function call brcmf_sdbrcm_wd_timer() directly. Reviewed-by: Franky Lin Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index ec9f5ed..e8317b2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -1122,14 +1122,6 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) } #ifdef CONFIG_PM_SLEEP -static void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) -{ - if (enable) - brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); - else - brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); -} - static int brcmf_sdio_suspend(struct device *dev) { mmc_pm_flag_t sdio_flags; @@ -1153,7 +1145,7 @@ static int brcmf_sdio_suspend(struct device *dev) return ret; } - brcmf_sdio_wdtmr_enable(sdiodev, false); + brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); return ret; } @@ -1163,7 +1155,7 @@ static int brcmf_sdio_resume(struct device *dev) struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - brcmf_sdio_wdtmr_enable(sdiodev, true); + brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); atomic_set(&sdiodev->suspend, false); return 0; } -- cgit v1.1 From a39be27b49e309bb790bea93a2595732f93e5fcb Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:58 +0100 Subject: brcmfmac: use consistent function names in bcmsdh.c Functions in bcmsdh.c that are called with struct brcmf_sdio_dev instance are renamed consistently with brcmf_sdiod_ prefix. Also removing brcmf_sdioh_attach/detach() functions and merge it with brcmf_sdiod_probe/remove(). Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 274 ++++++++--------- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 324 ++++++++++----------- .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 288 +++++++++--------- .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 44 +-- 4 files changed, 452 insertions(+), 478 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index e8317b2..981ca92 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -57,7 +57,7 @@ #define SDIO_WAIT_F2RDY 3000 -static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id) +static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id) { struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; @@ -77,7 +77,7 @@ static irqreturn_t brcmf_sdio_oob_irqhandler(int irq, void *dev_id) return IRQ_HANDLED; } -static void brcmf_sdio_ib_irqhandler(struct sdio_func *func) +static void brcmf_sdiod_ib_irqhandler(struct sdio_func *func) { struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; @@ -88,11 +88,11 @@ static void brcmf_sdio_ib_irqhandler(struct sdio_func *func) } /* dummy handler for SDIO function 2 interrupt */ -static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func) +static void brcmf_sdiod_dummy_irqhandler(struct sdio_func *func) { } -static bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) +static bool brcmf_sdiod_pm_resume_error(struct brcmf_sdio_dev *sdiodev) { bool is_err = false; #ifdef CONFIG_PM_SLEEP @@ -101,8 +101,8 @@ static bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) return is_err; } -static void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, - wait_queue_head_t *wq) +static void brcmf_sdiod_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, + wait_queue_head_t *wq) { #ifdef CONFIG_PM_SLEEP int retry = 0; @@ -111,7 +111,7 @@ static void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, #endif } -int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) +int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) { int ret = 0; u8 data; @@ -121,7 +121,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", sdiodev->pdata->oob_irq_nr); ret = request_irq(sdiodev->pdata->oob_irq_nr, - brcmf_sdio_oob_irqhandler, + brcmf_sdiod_oob_irqhandler, sdiodev->pdata->oob_irq_flags, "brcmf_oob_intr", &sdiodev->func[1]->dev); @@ -145,36 +145,36 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) sdio_claim_host(sdiodev->func[1]); /* must configure SDIO_CCCR_IENx to enable irq */ - data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); + data = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_IENx, &ret); data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret); /* redirect, configure and enable io for interrupt signal */ data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) data |= SDIO_SEPINT_ACT_HI; - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); sdio_release_host(sdiodev->func[1]); } else { brcmf_dbg(SDIO, "Entering\n"); sdio_claim_host(sdiodev->func[1]); - sdio_claim_irq(sdiodev->func[1], brcmf_sdio_ib_irqhandler); - sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler); + sdio_claim_irq(sdiodev->func[1], brcmf_sdiod_ib_irqhandler); + sdio_claim_irq(sdiodev->func[2], brcmf_sdiod_dummy_irqhandler); sdio_release_host(sdiodev->func[1]); } return 0; } -int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) +int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) { brcmf_dbg(SDIO, "Entering\n"); if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { sdio_claim_host(sdiodev->func[1]); - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); - brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); sdio_release_host(sdiodev->func[1]); if (sdiodev->oob_irq_requested) { @@ -197,7 +197,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) return 0; } -static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, +static inline int brcmf_sdiod_f0_write_byte(struct brcmf_sdio_dev *sdiodev, uint regaddr, u8 *byte) { struct sdio_func *sdfunc = sdiodev->func[0]; @@ -227,20 +227,20 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev, return err_ret; } -static int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, +static int brcmf_sdiod_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, uint regaddr, u8 *byte) { int err_ret; brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); - if (brcmf_pm_resume_error(sdiodev)) + brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); + if (brcmf_sdiod_pm_resume_error(sdiodev)) return -EIO; if (rw && func == 0) { /* handle F0 separately */ - err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte); + err_ret = brcmf_sdiod_f0_write_byte(sdiodev, regaddr, byte); } else { if (rw) /* CMD52 Write */ sdio_writeb(sdiodev->func[func], *byte, regaddr, @@ -272,7 +272,7 @@ static int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, return err_ret; } -static int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, +static int brcmf_sdiod_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, uint addr, u32 *word, uint nbytes) { @@ -286,8 +286,8 @@ static int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", rw, func, addr, nbytes); - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); - if (brcmf_pm_resume_error(sdiodev)) + brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); + if (brcmf_sdiod_pm_resume_error(sdiodev)) return -EIO; if (rw) { /* CMD52 Write */ @@ -317,7 +317,7 @@ static int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, } static int -brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) +brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) { int err = 0, i; u8 addr[3]; @@ -332,7 +332,7 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) do { if (retry) usleep_range(1000, 2000); - err = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, + err = brcmf_sdiod_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i, &addr[i]); } while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); @@ -348,13 +348,13 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) } static int -brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) +brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) { uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; if (bar0 != sdiodev->sbwad) { - err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); + err = brcmf_sdiod_set_sbaddr_window(sdiodev, bar0); if (err) return err; @@ -369,8 +369,8 @@ brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) return 0; } -static int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - void *data, bool write) +static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, + void *data, bool write) { u8 func_num, reg_size; s32 retry = 0; @@ -392,7 +392,7 @@ static int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, func_num = SDIO_FUNC_1; reg_size = 4; - ret = brcmf_sdio_addrprep(sdiodev, reg_size, &addr); + ret = brcmf_sdiod_addrprep(sdiodev, reg_size, &addr); if (ret) goto done; } @@ -403,10 +403,10 @@ static int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, if (retry) /* wait for 1 ms till bus get settled down */ usleep_range(1000, 2000); if (reg_size == 1) - ret = brcmf_sdioh_request_byte(sdiodev, write, + ret = brcmf_sdiod_request_byte(sdiodev, write, func_num, addr, data); else - ret = brcmf_sdioh_request_word(sdiodev, write, + ret = brcmf_sdiod_request_word(sdiodev, write, func_num, addr, data, 4); } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); @@ -417,13 +417,13 @@ done: return ret; } -u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) { u8 data; int retval; brcmf_dbg(SDIO, "addr:0x%08x\n", addr); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, false); brcmf_dbg(SDIO, "data:0x%02x\n", data); if (ret) @@ -432,13 +432,13 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) return data; } -u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) +u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) { u32 data; int retval; brcmf_dbg(SDIO, "addr:0x%08x\n", addr); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, false); brcmf_dbg(SDIO, "data:0x%08x\n", data); if (ret) @@ -447,37 +447,37 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) return data; } -void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, +void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, int *ret) { int retval; brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, true); if (ret) *ret = retval; } -void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, +void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, int *ret) { int retval; brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); - retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, true); if (ret) *ret = retval; } -static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, +static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, bool write, u32 addr, struct sk_buff *pkt) { unsigned int req_sz; - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); - if (brcmf_pm_resume_error(sdiodev)) + brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); + if (brcmf_sdiod_pm_resume_error(sdiodev)) return -EIO; /* Single skb use the standard mmc interface */ @@ -500,7 +500,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, } /** - * brcmf_sdio_sglist_rw - SDIO interface function for block data access + * brcmf_sdiod_sglist_rw - SDIO interface function for block data access * @sdiodev: brcmfmac sdio device * @fn: SDIO function number * @write: direction flag @@ -511,9 +511,9 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, * stack for block data access. It assumes that the skb passed down by the * caller has already been padded and aligned. */ -static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, - bool write, u32 addr, - struct sk_buff_head *pktlist) +static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, + bool write, u32 addr, + struct sk_buff_head *pktlist) { unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; unsigned int max_req_sz, orig_offset, dst_offset; @@ -531,8 +531,8 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, if (!pktlist->qlen) return -EINVAL; - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); - if (brcmf_pm_resume_error(sdiodev)) + brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); + if (brcmf_sdiod_pm_resume_error(sdiodev)) return -EIO; target_list = pktlist; @@ -680,8 +680,8 @@ exit: } int -brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes) +brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes) { struct sk_buff *mypkt; int err; @@ -693,7 +693,7 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, return -EIO; } - err = brcmf_sdcard_recv_pkt(sdiodev, addr, fn, flags, mypkt); + err = brcmf_sdiod_recv_pkt(sdiodev, addr, fn, flags, mypkt); if (!err) memcpy(buf, mypkt->data, nbytes); @@ -702,8 +702,8 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, } int -brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff *pkt) +brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff *pkt) { uint width; int err = 0; @@ -712,18 +712,18 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, fn, addr, pkt->len); width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdio_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, width, &addr); if (err) goto done; - err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt); + err = brcmf_sdiod_buffrw(sdiodev, fn, false, addr, pkt); done: return err; } -int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq, uint totlen) +int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq, uint totlen) { struct sk_buff *glom_skb; struct sk_buff *skb; @@ -734,17 +734,17 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, fn, addr, pktq->qlen); width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdio_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, width, &addr); if (err) goto done; if (pktq->qlen == 1) - err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq->next); + err = brcmf_sdiod_buffrw(sdiodev, fn, false, addr, pktq->next); else if (!sdiodev->sg_support) { glom_skb = brcmu_pkt_buf_get_skb(totlen); if (!glom_skb) return -ENOMEM; - err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, glom_skb); + err = brcmf_sdiod_buffrw(sdiodev, fn, false, addr, glom_skb); if (err) goto done; @@ -753,15 +753,15 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, skb_pull(glom_skb, skb->len); } } else - err = brcmf_sdio_sglist_rw(sdiodev, fn, false, addr, pktq); + err = brcmf_sdiod_sglist_rw(sdiodev, fn, false, addr, pktq); done: return err; } int -brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes) +brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes) { struct sk_buff *mypkt; uint width; @@ -777,10 +777,10 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, memcpy(mypkt->data, buf, nbytes); width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdio_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, width, &addr); if (!err) - err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, mypkt); + err = brcmf_sdiod_buffrw(sdiodev, fn, true, addr, mypkt); brcmu_pkt_buf_free_skb(mypkt); return err; @@ -788,8 +788,8 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, } int -brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq) +brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq) { struct sk_buff *skb; uint width; @@ -799,25 +799,25 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, fn, addr, pktq->qlen); width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdio_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, width, &addr); if (err) return err; if (pktq->qlen == 1 || !sdiodev->sg_support) skb_queue_walk(pktq, skb) { - err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, skb); + err = brcmf_sdiod_buffrw(sdiodev, fn, true, addr, skb); if (err) break; } else - err = brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq); + err = brcmf_sdiod_sglist_rw(sdiodev, fn, true, addr, pktq); return err; } int -brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, - u8 *data, uint size) +brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, + u8 *data, uint size) { int bcmerror = 0; struct sk_buff *pkt; @@ -844,7 +844,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, /* Do the transfer(s) */ while (size) { /* Set the backplane window to include the start address */ - bcmerror = brcmf_sdcard_set_sbaddr_window(sdiodev, address); + bcmerror = brcmf_sdiod_set_sbaddr_window(sdiodev, address); if (bcmerror) break; @@ -858,8 +858,8 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, skb_put(pkt, dsize); if (write) memcpy(pkt->data, data, dsize); - bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write, - sdaddr, pkt); + bcmerror = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_1, write, + sdaddr, pkt); if (bcmerror) { brcmf_err("membytes transfer failed\n"); break; @@ -881,7 +881,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, dev_kfree_skb(pkt); /* Return the window to backplane enumeration space for core access */ - if (brcmf_sdcard_set_sbaddr_window(sdiodev, sdiodev->sbwad)) + if (brcmf_sdiod_set_sbaddr_window(sdiodev, sdiodev->sbwad)) brcmf_err("FAILED to set window back to 0x%x\n", sdiodev->sbwad); @@ -890,41 +890,64 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, return bcmerror; } -int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) { char t_func = (char)fn; brcmf_dbg(SDIO, "Enter\n"); /* issue abort cmd52 command through F0 */ - brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, + brcmf_sdiod_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, SDIO_CCCR_ABORT, &t_func); brcmf_dbg(SDIO, "Exit\n"); return 0; } -static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) +static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) +{ + sdiodev->bus_if->state = BRCMF_BUS_DOWN; + + if (sdiodev->bus) { + brcmf_sdbrcm_disconnect(sdiodev->bus); + sdiodev->bus = NULL; + } + + /* Disable Function 2 */ + sdio_claim_host(sdiodev->func[2]); + sdio_disable_func(sdiodev->func[2]); + sdio_release_host(sdiodev->func[2]); + + /* Disable Function 1 */ + sdio_claim_host(sdiodev->func[1]); + sdio_disable_func(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); + + sdiodev->sbwad = 0; + + return 0; +} + +static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) { - int err_ret = 0; - struct mmc_host *host; struct sdio_func *func; + struct mmc_host *host; uint max_blocks; - - brcmf_dbg(SDIO, "\n"); + int ret = 0; sdiodev->num_funcs = 2; sdio_claim_host(sdiodev->func[1]); - err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); - if (err_ret) { + ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); + if (ret) { brcmf_err("Failed to set F1 blocksize\n"); + sdio_release_host(sdiodev->func[1]); goto out; } - - err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); - if (err_ret) { + ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); + if (ret) { brcmf_err("Failed to set F2 blocksize\n"); + sdio_release_host(sdiodev->func[1]); goto out; } @@ -932,14 +955,15 @@ static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) sdiodev->func[2]->enable_timeout = SDIO_WAIT_F2RDY; /* Enable Function 1 */ - err_ret = sdio_enable_func(sdiodev->func[1]); - if (err_ret) { - brcmf_err("Failed to enable F1 Err: 0x%08x\n", err_ret); + ret = sdio_enable_func(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); + if (ret) { + brcmf_err("Failed to enable F1: err=%d\n", ret); goto out; } /* - * determine host related variables after brcmf_sdio_probe() + * determine host related variables after brcmf_sdiod_probe() * as func->cur_blksize is properly set and F2 init has been * completed successfully. */ @@ -952,63 +976,17 @@ static int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) sdiodev->max_segment_count = min_t(uint, host->max_segs, SG_MAX_SINGLE_ALLOC); sdiodev->max_segment_size = host->max_seg_size; -out: - sdio_release_host(sdiodev->func[1]); - brcmf_dbg(SDIO, "Done\n"); - return err_ret; -} - -static void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) -{ - brcmf_dbg(SDIO, "\n"); - - /* Disable Function 2 */ - sdio_claim_host(sdiodev->func[2]); - sdio_disable_func(sdiodev->func[2]); - sdio_release_host(sdiodev->func[2]); - - /* Disable Function 1 */ - sdio_claim_host(sdiodev->func[1]); - sdio_disable_func(sdiodev->func[1]); - sdio_release_host(sdiodev->func[1]); - -} - -static int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) -{ - sdiodev->bus_if->state = BRCMF_BUS_DOWN; - - if (sdiodev->bus) { - brcmf_sdbrcm_disconnect(sdiodev->bus); - sdiodev->bus = NULL; - } - - brcmf_sdioh_detach(sdiodev); - - sdiodev->sbwad = 0; - - return 0; -} - -static int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) -{ - int ret = 0; - - ret = brcmf_sdioh_attach(sdiodev); - if (ret) - goto out; /* try to attach to the target device */ sdiodev->bus = brcmf_sdbrcm_probe(sdiodev); if (!sdiodev->bus) { - brcmf_err("device attach failed\n"); ret = -ENODEV; goto out; } out: if (ret) - brcmf_sdio_remove(sdiodev); + brcmf_sdiod_remove(sdiodev); return ret; } @@ -1075,8 +1053,8 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, init_waitqueue_head(&sdiodev->request_word_wait); init_waitqueue_head(&sdiodev->request_buffer_wait); - brcmf_dbg(SDIO, "F2 found, calling brcmf_sdio_probe...\n"); - err = brcmf_sdio_probe(sdiodev); + brcmf_dbg(SDIO, "F2 found, calling brcmf_sdiod_probe...\n"); + err = brcmf_sdiod_probe(sdiodev); if (err) { brcmf_err("F2 error, probe failed %d...\n", err); goto fail; @@ -1109,7 +1087,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) bus_if = dev_get_drvdata(&func->dev); if (bus_if) { sdiodev = bus_if->bus_priv.sdio; - brcmf_sdio_remove(sdiodev); + brcmf_sdiod_remove(sdiodev); dev_set_drvdata(&sdiodev->func[1]->dev, NULL); dev_set_drvdata(&sdiodev->func[2]->dev, NULL); @@ -1122,7 +1100,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) } #ifdef CONFIG_PM_SLEEP -static int brcmf_sdio_suspend(struct device *dev) +static int brcmf_ops_sdio_suspend(struct device *dev) { mmc_pm_flag_t sdio_flags; struct brcmf_bus *bus_if = dev_get_drvdata(dev); @@ -1150,7 +1128,7 @@ static int brcmf_sdio_suspend(struct device *dev) return ret; } -static int brcmf_sdio_resume(struct device *dev) +static int brcmf_ops_sdio_resume(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; @@ -1161,8 +1139,8 @@ static int brcmf_sdio_resume(struct device *dev) } static const struct dev_pm_ops brcmf_sdio_pm_ops = { - .suspend = brcmf_sdio_suspend, - .resume = brcmf_sdio_resume, + .suspend = brcmf_ops_sdio_suspend, + .resume = brcmf_ops_sdio_resume, }; #endif /* CONFIG_PM_SLEEP */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index c42d5a0..3d8a1a8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -621,8 +621,8 @@ r_sdreg32(struct brcmf_sdio *bus, u32 *regvar, u32 offset) u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); int ret; - *regvar = brcmf_sdio_regrl(bus->sdiodev, - bus->ci->c_inf[idx].base + offset, &ret); + *regvar = brcmf_sdiod_regrl(bus->sdiodev, + bus->ci->c_inf[idx].base + offset, &ret); return ret; } @@ -633,9 +633,9 @@ w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); int ret; - brcmf_sdio_regwl(bus->sdiodev, - bus->ci->c_inf[idx].base + reg_offset, - regval, &ret); + brcmf_sdiod_regwl(bus->sdiodev, + bus->ci->c_inf[idx].base + reg_offset, + regval, &ret); return ret; } @@ -651,8 +651,8 @@ brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on) wr_val = (on << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); /* 1st KSO write goes to AOS wake up core if device is asleep */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - wr_val, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + wr_val, &err); if (err) { brcmf_err("SDIO_AOS KSO write error: %d\n", err); return err; @@ -682,15 +682,15 @@ brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on) * just one write attempt may fail, * read it back until it matches written value */ - rd_val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - &err); + rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + &err); if (((rd_val & bmask) == cmp_val) && !err) break; brcmf_dbg(SDIO, "KSO wr/rd retry:%d (max: %d) ERR:%x\n", try_cnt, MAX_KSO_ATTEMPTS, err); udelay(KSO_WAIT_US); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - wr_val, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + wr_val, &err); } while (try_cnt++ < MAX_KSO_ATTEMPTS); return err; @@ -721,16 +721,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) clkreq = bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + clkreq, &err); if (err) { brcmf_err("HT Avail request error: %d\n", err); return -EBADE; } /* Check current status */ - clkctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + clkctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { brcmf_err("HT Avail read error: %d\n", err); return -EBADE; @@ -739,8 +739,8 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) /* Go to pending and await interrupt if appropriate */ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { /* Allow only clock-available interrupt */ - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); if (err) { brcmf_err("Devctl error setting CA: %d\n", err); @@ -748,28 +748,28 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) } devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, + devctl, &err); brcmf_dbg(SDIO, "CLKCTL: set PENDING\n"); bus->clkstate = CLK_PENDING; return 0; } else if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, + devctl, &err); } /* Otherwise, wait here (polling) for HT Avail */ timeout = jiffies + msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - clkctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, - &err); + clkctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, + &err); if (time_after(jiffies, timeout)) break; else @@ -802,16 +802,16 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, + devctl, &err); } bus->clkstate = CLK_SDONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - clkreq, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + clkreq, &err); brcmf_dbg(SDIO, "CLKCTL: turned OFF\n"); if (err) { brcmf_err("Failed access turning clock off: %d\n", @@ -1037,18 +1037,18 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) rtx ? ", send NAK" : ""); if (abort) - brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); + brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_RF_TERM, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, + SFC_RF_TERM, &err); bus->sdcnt.f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_RFRAMEBCHI, &err); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_RFRAMEBCLO, &err); + hi = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_RFRAMEBCHI, &err); + lo = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_RFRAMEBCLO, &err); bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) @@ -1418,9 +1418,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) * packet and and copy into the chain. */ sdio_claim_host(bus->sdiodev->func[1]); - errcode = brcmf_sdcard_recv_chain(bus->sdiodev, - bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, &bus->glom, dlen); + errcode = brcmf_sdiod_recv_chain(bus->sdiodev, + bus->sdiodev->sbwad, + SDIO_FUNC_2, F2SYNC, + &bus->glom, dlen); sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2rxdata++; @@ -1614,10 +1615,8 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) } /* Read remain of frame body */ - sdret = brcmf_sdcard_recv_buf(bus->sdiodev, - bus->sdiodev->sbwad, - SDIO_FUNC_2, - F2SYNC, rbuf, rdlen); + sdret = brcmf_sdiod_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, + SDIO_FUNC_2, F2SYNC, rbuf, rdlen); bus->sdcnt.f2rxdata++; /* Control frame failures need retransmission */ @@ -1702,11 +1701,10 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) /* read header first for unknow frame length */ sdio_claim_host(bus->sdiodev->func[1]); if (!rd->len) { - ret = brcmf_sdcard_recv_buf(bus->sdiodev, - bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, - bus->rxhdr, - BRCMF_FIRSTREAD); + ret = brcmf_sdiod_recv_buf(bus->sdiodev, + bus->sdiodev->sbwad, + SDIO_FUNC_2, F2SYNC, + bus->rxhdr, BRCMF_FIRSTREAD); bus->sdcnt.f2rxhdrs++; if (ret < 0) { brcmf_err("RXHEADER FAILED: %d\n", @@ -1762,8 +1760,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) skb_pull(pkt, head_read); pkt_align(pkt, rd->len_left, bus->head_align); - ret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, pkt); + ret = brcmf_sdiod_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, + SDIO_FUNC_2, F2SYNC, pkt); bus->sdcnt.f2rxdata++; sdio_release_host(bus->sdiodev->func[1]); @@ -2118,8 +2116,8 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, goto done; sdio_claim_host(bus->sdiodev->func[1]); - ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, pktq); + ret = brcmf_sdiod_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, + SDIO_FUNC_2, F2SYNC, pktq); bus->sdcnt.f2txdata++; if (ret < 0) { @@ -2128,17 +2126,17 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, ret); bus->sdcnt.tx_sderrs++; - brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); + brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, + SFC_WF_TERM, NULL); bus->sdcnt.f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); + hi = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_WFRAMEBCHI, NULL); + lo = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_WFRAMEBCLO, NULL); bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -2251,11 +2249,11 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + saveclk = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); } if (err) brcmf_err("Failed to force clock for F2: err %d\n", err); @@ -2316,7 +2314,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) addr = bus->ci->c_inf[idx].base + offsetof(struct sdpcmd_regs, intstatus); - val = brcmf_sdio_regrl(bus->sdiodev, addr, &ret); + val = brcmf_sdiod_regrl(bus->sdiodev, addr, &ret); bus->sdcnt.f1regdata++; if (ret != 0) val = 0; @@ -2326,7 +2324,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) /* Clear interrupts */ if (val) { - brcmf_sdio_regwl(bus->sdiodev, addr, val, &ret); + brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret); bus->sdcnt.f1regdata++; } @@ -2359,8 +2357,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) #ifdef DEBUG /* Check for inconsistent device control */ - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); if (err) { brcmf_err("error reading DEVCTL: %d\n", err); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; @@ -2368,8 +2366,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) #endif /* DEBUG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + clkctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { brcmf_err("error reading CSR: %d\n", err); @@ -2380,16 +2378,16 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) devctl, clkctl); if (SBSDIO_HTAV(clkctl)) { - devctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_DEVICE_CTL, &err); + devctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_DEVICE_CTL, &err); if (err) { brcmf_err("error reading DEVCTL: %d\n", err); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, - devctl, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, + devctl, &err); if (err) { brcmf_err("error writing DEVCTL: %d\n", err); @@ -2483,9 +2481,10 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) int i; sdio_claim_host(bus->sdiodev->func[1]); - err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, - (u32) bus->ctrl_frame_len); + err = brcmf_sdiod_send_buf(bus->sdiodev, bus->sdiodev->sbwad, + SDIO_FUNC_2, F2SYNC, + bus->ctrl_frame_buf, + (u32)bus->ctrl_frame_len); if (err < 0) { /* On failure, abort the command and @@ -2494,20 +2493,20 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) err); bus->sdcnt.tx_sderrs++; - brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); + brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, + SFC_WF_TERM, &err); bus->sdcnt.f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCHI, - &err); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCLO, - &err); + hi = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_WFRAMEBCHI, + &err); + lo = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_WFRAMEBCLO, + &err); bus->sdcnt.f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -2631,8 +2630,8 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) /* Read console log struct */ addr = bus->console_addr + offsetof(struct rte_console, log_le); - rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le, - sizeof(c->log_le)); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le, + sizeof(c->log_le)); if (rv < 0) return rv; @@ -2657,7 +2656,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) /* Read the console buffer */ addr = le32_to_cpu(c->log_le.buf); - rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize); if (rv < 0) return rv; @@ -2701,8 +2700,8 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) int ret; bus->ctrl_frame_stat = false; - ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, frame, len); + ret = brcmf_sdiod_send_buf(bus->sdiodev, bus->sdiodev->sbwad, + SDIO_FUNC_2, F2SYNC, frame, len); if (ret < 0) { /* On failure, abort the command and terminate the frame */ @@ -2710,18 +2709,18 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) ret); bus->sdcnt.tx_sderrs++; - brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); + brcmf_sdiod_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, - SFC_WF_TERM, NULL); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, + SFC_WF_TERM, NULL); bus->sdcnt.f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_WFRAMEBCLO, NULL); + hi = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_WFRAMEBCHI, NULL); + lo = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_WFRAMEBCLO, NULL); bus->sdcnt.f1regdata += 2; if (hi == 0 && lo == 0) break; @@ -2868,7 +2867,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, */ sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_bus_sleep(bus, false, false); - rv = brcmf_sdio_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); sdio_release_host(bus->sdiodev->func[1]); if (rv < 0) return rv; @@ -2888,8 +2887,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, } /* Read hndrte_shared structure */ - rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, - sizeof(struct sdpcm_shared_le)); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, + sizeof(struct sdpcm_shared_le)); if (rv < 0) return rv; @@ -2925,22 +2924,22 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, /* obtain console information from device memory */ addr = sh->console_addr + offsetof(struct rte_console, log_le); - rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, - (u8 *)&sh_val, sizeof(u32)); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, + (u8 *)&sh_val, sizeof(u32)); if (rv < 0) return rv; console_ptr = le32_to_cpu(sh_val); addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); - rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, - (u8 *)&sh_val, sizeof(u32)); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, + (u8 *)&sh_val, sizeof(u32)); if (rv < 0) return rv; console_size = le32_to_cpu(sh_val); addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); - rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, - (u8 *)&sh_val, sizeof(u32)); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, + (u8 *)&sh_val, sizeof(u32)); if (rv < 0) return rv; console_index = le32_to_cpu(sh_val); @@ -2954,8 +2953,8 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, /* obtain the console data from device */ conbuf[console_size] = '\0'; - rv = brcmf_sdio_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf, - console_size); + rv = brcmf_sdiod_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf, + console_size); if (rv < 0) goto done; @@ -2992,8 +2991,8 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, return 0; } - error = brcmf_sdio_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr, - sizeof(struct brcmf_trap_info)); + error = brcmf_sdiod_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr, + sizeof(struct brcmf_trap_info)); if (error < 0) return error; @@ -3036,14 +3035,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, sdio_claim_host(bus->sdiodev->func[1]); if (sh->assert_file_addr != 0) { - error = brcmf_sdio_ramrw(bus->sdiodev, false, - sh->assert_file_addr, (u8 *)file, 80); + error = brcmf_sdiod_ramrw(bus->sdiodev, false, + sh->assert_file_addr, (u8 *)file, 80); if (error < 0) return error; } if (sh->assert_exp_addr != 0) { - error = brcmf_sdio_ramrw(bus->sdiodev, false, - sh->assert_exp_addr, (u8 *)expr, 80); + error = brcmf_sdiod_ramrw(bus->sdiodev, false, + sh->assert_exp_addr, (u8 *)expr, 80); if (error < 0) return error; } @@ -3248,8 +3247,8 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) while (offset < fw->size) { len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK : fw->size - offset; - err = brcmf_sdio_ramrw(bus->sdiodev, true, address, - (u8 *)&fw->data[offset], len); + err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, + (u8 *)&fw->data[offset], len); if (err) { brcmf_err("error %d on writing %d membytes at 0x%08x\n", err, len, address); @@ -3399,9 +3398,9 @@ static bool brcmf_sdbrcm_sr_capable(struct brcmf_sdio *bus) /* read PMU chipcontrol register 3*/ addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); - brcmf_sdio_regwl(bus->sdiodev, addr, 3, NULL); + brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL); addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); - reg = brcmf_sdio_regrl(bus->sdiodev, addr, NULL); + reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL); return (bool)reg; } @@ -3413,33 +3412,31 @@ static void brcmf_sdbrcm_sr_init(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); - val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, - &err); + val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err); if (err) { brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n"); return; } val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT; - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, - val, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err); if (err) { brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n"); return; } /* Add CMD14 Support */ - brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, - (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | - SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), - &err); + brcmf_sdiod_regwb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP, + (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT | + SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT), + &err); if (err) { brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n"); return; } - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - SBSDIO_FORCE_HT, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + SBSDIO_FORCE_HT, &err); if (err) { brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n"); return; @@ -3462,8 +3459,7 @@ static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus) if (bus->ci->c_inf[1].rev < 12) return 0; - val = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - &err); + val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, &err); if (err) { brcmf_err("error reading SBSDIO_FUNC1_SLEEPCSR\n"); return err; @@ -3472,8 +3468,8 @@ static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus) if (!(val & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK)) { val |= (SBSDIO_FUNC1_SLEEPCSR_KSO_EN << SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, - val, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + val, &err); if (err) { brcmf_err("error writing SBSDIO_FUNC1_SLEEPCSR\n"); return err; @@ -3592,11 +3588,11 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) goto exit; /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + saveclk = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); } if (err) { brcmf_err("Failed to force clock for F2: err %d\n", err); @@ -3618,7 +3614,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) w_sdreg32(bus, bus->hostintmask, offsetof(struct sdpcmd_regs, hostintmask)); - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_WATERMARK, 8, &err); } else { /* Disable F2 again */ sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); @@ -3629,12 +3625,12 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) brcmf_sdbrcm_sr_init(bus); } else { /* Restore previous clock setting */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - saveclk, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + saveclk, &err); } if (ret == 0) { - ret = brcmf_sdio_intr_register(bus->sdiodev); + ret = brcmf_sdiod_intr_register(bus->sdiodev); if (ret != 0) brcmf_err("intr register failed:%d\n", ret); } @@ -3704,9 +3700,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) u8 devpend; sdio_claim_host(bus->sdiodev->func[1]); - devpend = brcmf_sdio_regrb(bus->sdiodev, - SDIO_CCCR_INTx, - NULL); + devpend = brcmf_sdiod_regrb(bus->sdiodev, + SDIO_CCCR_INTx, + NULL); sdio_release_host(bus->sdiodev->func[1]); intstatus = devpend & (INTR_STATUS_FUNC1 | @@ -3814,18 +3810,18 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus) sdio_claim_host(bus->sdiodev->func[1]); pr_debug("F1 signature read @0x18000000=0x%4x\n", - brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); + brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); /* * Force PLL off until brcmf_sdio_chip_attach() * programs PLL control regs */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - BRCMF_INIT_CLKCTL1, &err); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + BRCMF_INIT_CLKCTL1, &err); if (!err) - clkctl = brcmf_sdio_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); + clkctl = brcmf_sdiod_regrb(bus->sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { brcmf_err("ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", @@ -3857,33 +3853,33 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus) } /* Set card control so an SDIO card reset does a WLAN backplane reset */ - reg_val = brcmf_sdio_regrb(bus->sdiodev, - SDIO_CCCR_BRCM_CARDCTRL, &err); + reg_val = brcmf_sdiod_regrb(bus->sdiodev, + SDIO_CCCR_BRCM_CARDCTRL, &err); if (err) goto fail; reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; - brcmf_sdio_regwb(bus->sdiodev, - SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); + brcmf_sdiod_regwb(bus->sdiodev, + SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); if (err) goto fail; /* set PMUControl so a backplane reset does PMU state reload */ reg_addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucontrol); - reg_val = brcmf_sdio_regrl(bus->sdiodev, - reg_addr, - &err); + reg_val = brcmf_sdiod_regrl(bus->sdiodev, + reg_addr, + &err); if (err) goto fail; reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); - brcmf_sdio_regwl(bus->sdiodev, - reg_addr, - reg_val, - &err); + brcmf_sdiod_regwl(bus->sdiodev, + reg_addr, + reg_val, + &err); if (err) goto fail; @@ -3926,7 +3922,7 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) bus->rxflow = false; /* Done with backplane-dependent accesses, can drop clock... */ - brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); sdio_release_host(bus->sdiodev->func[1]); @@ -4005,7 +4001,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) if (bus) { /* De-register interrupt handler */ - brcmf_sdio_intr_unregister(bus->sdiodev); + brcmf_sdiod_intr_unregister(bus->sdiodev); cancel_work_sync(&bus->datawork); if (bus->brcmf_wq) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index b612808d..5f39f28 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -112,9 +112,9 @@ brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, coreid); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbidhigh), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbidhigh), + NULL); return SBCOREREV(regdata); } @@ -140,9 +140,9 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, if (idx == BRCMF_MAX_CORENUM) return false; - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + NULL); regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT | SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK); return (SSB_TMSLOW_CLOCK == regdata); @@ -160,13 +160,13 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, if (idx == BRCMF_MAX_CORENUM) return false; - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + NULL); ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK; - regdata = brcmf_sdio_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + NULL); ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0); return ret; @@ -182,79 +182,79 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, coreid); base = ci->c_inf[idx].base; - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); + regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); if (regdata & SSB_TMSLOW_RESET) return; - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); + regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL); if ((regdata & SSB_TMSLOW_CLOCK) != 0) { /* * set target reject and spin until busy is clear * (preserve core-specific bits) */ - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), - NULL); - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), - regdata | SSB_TMSLOW_REJECT, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbtmstatelow), NULL); + brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow), + regdata | SSB_TMSLOW_REJECT, NULL); - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbtmstatelow), NULL); udelay(1); - SPINWAIT((brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbtmstatehigh), - NULL) & - SSB_TMSHIGH_BUSY), 100000); - - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbtmstatehigh), - NULL); + SPINWAIT((brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbtmstatehigh), + NULL) & + SSB_TMSHIGH_BUSY), 100000); + + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbtmstatehigh), + NULL); if (regdata & SSB_TMSHIGH_BUSY) brcmf_err("core state still busy\n"); - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow), + NULL); if (regdata & SSB_IDLOW_INITIATOR) { - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbimstate), + NULL); regdata |= SSB_IMSTATE_REJECT; - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate), - regdata, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL); + brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate), + regdata, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbimstate), + NULL); udelay(1); - SPINWAIT((brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL) & - SSB_IMSTATE_BUSY), 100000); + SPINWAIT((brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbimstate), + NULL) & + SSB_IMSTATE_BUSY), 100000); } /* set reset and reject while enabling the clocks */ regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET; - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), - regdata, NULL); - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbtmstatelow), - NULL); + brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow), + regdata, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbtmstatelow), NULL); udelay(10); /* clear the initiator reject bit */ - regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(base, sbidlow), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow), + NULL); if (regdata & SSB_IDLOW_INITIATOR) { - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(base, sbimstate), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(base, sbimstate), + NULL); regdata &= ~SSB_IMSTATE_REJECT; - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbimstate), - regdata, NULL); + brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate), + regdata, NULL); } } /* leave reset and reject asserted */ - brcmf_sdio_regwl(sdiodev, CORE_SB(base, sbtmstatelow), - (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL); + brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow), + (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL); udelay(1); } @@ -270,9 +270,9 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, return; /* if core is already in reset, just return */ - regdata = brcmf_sdio_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + NULL); if ((regdata & BCMA_RESET_CTL_RESET) != 0) return; @@ -281,24 +281,24 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, * extra 10ms is taken into account for firmware load stage * after 10300us carry on disabling the core anyway */ - SPINWAIT(brcmf_sdio_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_ST, - NULL), 10300); - regdata = brcmf_sdio_regrl(sdiodev, + SPINWAIT(brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_ST, - NULL); + NULL), 10300); + regdata = brcmf_sdiod_regrl(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_ST, + NULL); if (regdata) brcmf_err("disabling core 0x%x with reset status %x\n", coreid, regdata); - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - BCMA_RESET_CTL_RESET, NULL); + brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + BCMA_RESET_CTL_RESET, NULL); udelay(1); - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - core_bits, NULL); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); + brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + core_bits, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + NULL); usleep_range(10, 20); } @@ -325,47 +325,47 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, * set reset while enabling the clock and * forcing them on throughout the core */ - brcmf_sdio_regwl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET, - NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + brcmf_sdiod_regwl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET, + NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + NULL); udelay(1); /* clear any serror */ - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), + NULL); if (regdata & SSB_TMSHIGH_SERR) - brcmf_sdio_regwl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), - 0, NULL); + brcmf_sdiod_regwl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatehigh), + 0, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbimstate), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), + NULL); if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) - brcmf_sdio_regwl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbimstate), - regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO), - NULL); + brcmf_sdiod_regwl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbimstate), + regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO), + NULL); /* clear reset and allow it to propagate throughout the core */ - brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + NULL); udelay(1); /* leave clock enabled */ - brcmf_sdio_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - SSB_TMSLOW_CLOCK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - CORE_SB(ci->c_inf[idx].base, sbtmstatelow), - NULL); + brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + SSB_TMSLOW_CLOCK, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_SB(ci->c_inf[idx].base, sbtmstatelow), + NULL); udelay(1); } @@ -384,21 +384,21 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); /* now do initialization sequence */ - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - 0, NULL); - regdata = brcmf_sdio_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - NULL); + brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + NULL); + brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + 0, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + NULL); udelay(1); - brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - core_bits | BCMA_IOCTL_CLK, NULL); - regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); + brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + core_bits | BCMA_IOCTL_CLK, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, + NULL); udelay(1); } @@ -450,9 +450,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, */ ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; ci->c_inf[0].base = SI_ENUM_BASE; - regdata = brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(ci->c_inf[0].base, chipid), - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, + CORE_CC_REG(ci->c_inf[0].base, chipid), + NULL); ci->chip = regdata & CID_ID_MASK; ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && @@ -607,7 +607,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) /* Try forcing SDIO core to do ALPAvail request only */ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); if (err) { brcmf_err("error writing for HT off\n"); return err; @@ -615,8 +615,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) /* If register supported, wait for ALPAvail and then force ALP */ /* This may take up to 15 milliseconds */ - clkval = brcmf_sdio_regrb(sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, NULL); + clkval = brcmf_sdiod_regrb(sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, NULL); if ((clkval & ~SBSDIO_AVBITS) != clkset) { brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n", @@ -624,8 +624,8 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) return -EACCES; } - SPINWAIT(((clkval = brcmf_sdio_regrb(sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, NULL)), + SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), PMU_MAX_TRANSITION_DLY); if (!SBSDIO_ALPAV(clkval)) { @@ -635,11 +635,11 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) } clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); udelay(65); /* Also, disable the extra SDIO pull-ups */ - brcmf_sdio_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); return 0; } @@ -654,16 +654,16 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id); /* get chipcommon capabilites */ - ci->c_inf[0].caps = brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(base, capabilities), - NULL); + ci->c_inf[0].caps = brcmf_sdiod_regrl(sdiodev, + CORE_CC_REG(base, capabilities), + NULL); /* get pmu caps & rev */ if (ci->c_inf[0].caps & CC_CAP_PMU) { ci->pmucaps = - brcmf_sdio_regrl(sdiodev, - CORE_CC_REG(base, pmucapabilities), - NULL); + brcmf_sdiod_regrl(sdiodev, + CORE_CC_REG(base, pmucapabilities), + NULL); ci->pmurev = ci->pmucaps & PCAP_REV_MASK; } @@ -703,10 +703,10 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, brcmf_sdio_chip_buscoresetup(sdiodev, ci); - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup), - 0, NULL); - brcmf_sdio_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), - 0, NULL); + brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup), + 0, NULL); + brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), + 0, NULL); *ci_ptr = ci; return 0; @@ -784,12 +784,12 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, } } addr = CORE_CC_REG(base, chipcontrol_addr); - brcmf_sdio_regwl(sdiodev, addr, 1, NULL); - cc_data_temp = brcmf_sdio_regrl(sdiodev, addr, NULL); + brcmf_sdiod_regwl(sdiodev, addr, 1, NULL); + cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL); cc_data_temp &= ~str_mask; drivestrength_sel <<= str_shift; cc_data_temp |= drivestrength_sel; - brcmf_sdio_regwl(sdiodev, addr, cc_data_temp, NULL); + brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL); brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n", str_tab[i].strength, drivestrength, cc_data_temp); @@ -816,8 +816,8 @@ brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr, memset(nvram_ularray, 0xaa, nvram_sz); /* Read the vars list to temp buffer for comparison */ - err = brcmf_sdio_ramrw(sdiodev, false, nvram_addr, nvram_ularray, - nvram_sz); + err = brcmf_sdiod_ramrw(sdiodev, false, nvram_addr, nvram_ularray, + nvram_sz); if (err) { brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", err, nvram_sz, nvram_addr); @@ -850,7 +850,7 @@ static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev, nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase; /* Write the vars list */ - err = brcmf_sdio_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz); + err = brcmf_sdiod_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz); if (err) { brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n", err, nvram_sz, nvram_addr); @@ -874,8 +874,8 @@ static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev, nvram_addr, nvram_sz, token); /* Write the length token to the last word */ - if (brcmf_sdio_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase), - (u8 *)&token_le, 4)) + if (brcmf_sdiod_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase), + (u8 *)&token_le, 4)) return false; return true; @@ -891,7 +891,7 @@ brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); /* clear length token */ - brcmf_sdio_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4); + brcmf_sdiod_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4); } static bool @@ -913,7 +913,7 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); reg_addr = ci->c_inf[core_idx].base; reg_addr += offsetof(struct sdpcmd_regs, intstatus); - brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); @@ -942,11 +942,11 @@ brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); reg_addr = ci->c_inf[core_idx].base; reg_addr += offsetof(struct sdpcmd_regs, intstatus); - brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); + brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); /* Write reset vector to address 0 */ - brcmf_sdio_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, - sizeof(ci->rst_vec)); + brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, + sizeof(ci->rst_vec)); /* restore ARM */ ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 414aa16..4d71eb0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -184,16 +184,16 @@ struct brcmf_sdio_dev { }; /* Register/deregister interrupt handler. */ -int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); -int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev); /* sdio device register access interface */ -u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, - int *ret); -void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, - int *ret); +u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, + int *ret); +void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, + int *ret); /* Buffer transfer to/from device (client) core via cmd53. * fn: function number @@ -207,17 +207,17 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, * Returns 0 or error code. * NOTE: Async operation is not currently supported. */ -int brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq); -int brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); - -int brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff *pkt); -int brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); -int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq, uint totlen); +int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq); +int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes); + +int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff *pkt); +int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes); +int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq, uint totlen); /* Flags bits */ @@ -233,11 +233,11 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, * nbytes: number of bytes to transfer to/from buf * Returns 0 or error code. */ -int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, - u8 *data, uint size); +int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, + u8 *data, uint size); /* Issue an abort to the specified function */ -int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); +int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev); void brcmf_sdbrcm_disconnect(struct brcmf_sdio *bus); -- cgit v1.1 From a7cdd821e37fa5809ce1fb3793ab0e0e7e6e9d75 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:58:59 +0100 Subject: brcmfmac: reduce function parameters in sdio send/receive calls The SDIO send and receive functions in bcmsdh.c are always called with the same parameters. For the driver there is no use-case to call them otherwise so remove those parameters from function prototypes. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 73 ++++++++++------------ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 20 ++---- .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 20 +++--- 3 files changed, 46 insertions(+), 67 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 981ca92..cf21631 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -679,9 +679,7 @@ exit: return ret; } -int -brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes) +int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) { struct sk_buff *mypkt; int err; @@ -693,7 +691,7 @@ brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, return -EIO; } - err = brcmf_sdiod_recv_pkt(sdiodev, addr, fn, flags, mypkt); + err = brcmf_sdiod_recv_pkt(sdiodev, mypkt); if (!err) memcpy(buf, mypkt->data, nbytes); @@ -701,50 +699,47 @@ brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, return err; } -int -brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff *pkt) +int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt) { - uint width; + u32 addr = sdiodev->sbwad; int err = 0; - brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", - fn, addr, pkt->len); + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pkt->len); - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdiod_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); if (err) goto done; - err = brcmf_sdiod_buffrw(sdiodev, fn, false, addr, pkt); + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, pkt); done: return err; } -int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq, uint totlen) +int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, + struct sk_buff_head *pktq, uint totlen) { struct sk_buff *glom_skb; struct sk_buff *skb; - uint width; + u32 addr = sdiodev->sbwad; int err = 0; - brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", - fn, addr, pktq->qlen); + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", + addr, pktq->qlen); - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdiod_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); if (err) goto done; if (pktq->qlen == 1) - err = brcmf_sdiod_buffrw(sdiodev, fn, false, addr, pktq->next); + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, + pktq->next); else if (!sdiodev->sg_support) { glom_skb = brcmu_pkt_buf_get_skb(totlen); if (!glom_skb) return -ENOMEM; - err = brcmf_sdiod_buffrw(sdiodev, fn, false, addr, glom_skb); + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, + glom_skb); if (err) goto done; @@ -753,18 +748,17 @@ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, skb_pull(glom_skb, skb->len); } } else - err = brcmf_sdiod_sglist_rw(sdiodev, fn, false, addr, pktq); + err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, false, addr, + pktq); done: return err; } -int -brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes) +int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes) { struct sk_buff *mypkt; - uint width; + u32 addr = sdiodev->sbwad; int err; mypkt = brcmu_pkt_buf_get_skb(nbytes); @@ -776,41 +770,40 @@ brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, memcpy(mypkt->data, buf, nbytes); - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdiod_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); if (!err) - err = brcmf_sdiod_buffrw(sdiodev, fn, true, addr, mypkt); + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, addr, + mypkt); brcmu_pkt_buf_free_skb(mypkt); return err; } -int -brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq) +int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, + struct sk_buff_head *pktq) { struct sk_buff *skb; - uint width; + u32 addr = sdiodev->sbwad; int err; - brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", - fn, addr, pktq->qlen); + brcmf_dbg(SDIO, "addr = 0x%x, size = %d\n", addr, pktq->qlen); - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdiod_addrprep(sdiodev, width, &addr); + err = brcmf_sdiod_addrprep(sdiodev, 4, &addr); if (err) return err; if (pktq->qlen == 1 || !sdiodev->sg_support) skb_queue_walk(pktq, skb) { - err = brcmf_sdiod_buffrw(sdiodev, fn, true, addr, skb); + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, true, + addr, skb); if (err) break; } else - err = brcmf_sdiod_sglist_rw(sdiodev, fn, true, addr, pktq); + err = brcmf_sdiod_sglist_rw(sdiodev, SDIO_FUNC_2, true, addr, + pktq); return err; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 3d8a1a8..7fff4cc 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -1419,8 +1419,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) */ sdio_claim_host(bus->sdiodev->func[1]); errcode = brcmf_sdiod_recv_chain(bus->sdiodev, - bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, &bus->glom, dlen); sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2rxdata++; @@ -1615,8 +1613,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) } /* Read remain of frame body */ - sdret = brcmf_sdiod_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, rbuf, rdlen); + sdret = brcmf_sdiod_recv_buf(bus->sdiodev, rbuf, rdlen); bus->sdcnt.f2rxdata++; /* Control frame failures need retransmission */ @@ -1702,8 +1699,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) sdio_claim_host(bus->sdiodev->func[1]); if (!rd->len) { ret = brcmf_sdiod_recv_buf(bus->sdiodev, - bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, bus->rxhdr, BRCMF_FIRSTREAD); bus->sdcnt.f2rxhdrs++; if (ret < 0) { @@ -1760,8 +1755,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) skb_pull(pkt, head_read); pkt_align(pkt, rd->len_left, bus->head_align); - ret = brcmf_sdiod_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, pkt); + ret = brcmf_sdiod_recv_pkt(bus->sdiodev, pkt); bus->sdcnt.f2rxdata++; sdio_release_host(bus->sdiodev->func[1]); @@ -2116,8 +2110,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, goto done; sdio_claim_host(bus->sdiodev->func[1]); - ret = brcmf_sdiod_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, pktq); + ret = brcmf_sdiod_send_pkt(bus->sdiodev, pktq); bus->sdcnt.f2txdata++; if (ret < 0) { @@ -2481,9 +2474,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) int i; sdio_claim_host(bus->sdiodev->func[1]); - err = brcmf_sdiod_send_buf(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, - bus->ctrl_frame_buf, + err = brcmf_sdiod_send_buf(bus->sdiodev, bus->ctrl_frame_buf, (u32)bus->ctrl_frame_len); if (err < 0) { @@ -2700,8 +2691,7 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) int ret; bus->ctrl_frame_stat = false; - ret = brcmf_sdiod_send_buf(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, frame, len); + ret = brcmf_sdiod_send_buf(bus->sdiodev, frame, len); if (ret < 0) { /* On failure, abort the command and terminate the frame */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 4d71eb0..4c70cf2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -197,7 +197,6 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, /* Buffer transfer to/from device (client) core via cmd53. * fn: function number - * addr: backplane address (i.e. >= regsva from attach) * flags: backplane width, address increment, sync/async * buf: pointer to memory data buffer * nbytes: number of bytes to transfer to/from buf @@ -207,17 +206,14 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, * Returns 0 or error code. * NOTE: Async operation is not currently supported. */ -int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq); -int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); - -int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff *pkt); -int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); -int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq, uint totlen); +int brcmf_sdiod_send_pkt(struct brcmf_sdio_dev *sdiodev, + struct sk_buff_head *pktq); +int brcmf_sdiod_send_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes); + +int brcmf_sdiod_recv_pkt(struct brcmf_sdio_dev *sdiodev, struct sk_buff *pkt); +int brcmf_sdiod_recv_buf(struct brcmf_sdio_dev *sdiodev, u8 *buf, uint nbytes); +int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev, + struct sk_buff_head *pktq, uint totlen); /* Flags bits */ -- cgit v1.1 From 8141083c48192b63a39b77adffd9a8e0dcfab034 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Thu, 12 Dec 2013 11:59:00 +0100 Subject: brcmfmac: Move common BCDC code in single function. The BCDC functions query_dcmd and set_dcmd both create a msgbuf to be sent to dongle this code is very similar and for optimisation best put in a function. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 68 ++++++++++---------------- 1 file changed, 25 insertions(+), 43 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index 06848e4..ee86142 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -101,35 +101,41 @@ struct brcmf_proto_bcdc_header { * plus any space that might be needed * for bus alignment padding. */ -#define ROUND_UP_MARGIN 2048 /* Biggest bus block size possible for - * round off at the end of buffer - * Currently is SDIO - */ - struct brcmf_bcdc { u16 reqid; u8 bus_header[BUS_HEADER_LEN]; struct brcmf_proto_bcdc_dcmd msg; - unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN]; + unsigned char buf[BRCMF_DCMD_MAXLEN]; }; -static int brcmf_proto_bcdc_msg(struct brcmf_pub *drvr) + +static int +brcmf_proto_bcdc_msg(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, + uint len, bool set) { struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; - int len = le32_to_cpu(bcdc->msg.len) + - sizeof(struct brcmf_proto_bcdc_dcmd); + struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; + u32 flags; brcmf_dbg(BCDC, "Enter\n"); - /* NOTE : bcdc->msg.len holds the desired length of the buffer to be - * returned. Only up to BCDC_MAX_MSG_SIZE of this buffer area - * is actually sent to the dongle - */ - if (len > BCDC_MAX_MSG_SIZE) - len = BCDC_MAX_MSG_SIZE; + memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd)); + + msg->cmd = cpu_to_le32(cmd); + msg->len = cpu_to_le32(len); + flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT); + if (set) + flags |= BCDC_DCMD_SET; + flags = (flags & ~BCDC_DCMD_IF_MASK) | + (ifidx << BCDC_DCMD_IF_SHIFT); + msg->flags = cpu_to_le32(flags); + + if (buf) + memcpy(bcdc->buf, buf, len); /* Send request */ - return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); + return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, + len + sizeof(struct brcmf_proto_bcdc_dcmd)); } static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) @@ -161,19 +167,7 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); - memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd)); - - msg->cmd = cpu_to_le32(cmd); - msg->len = cpu_to_le32(len); - flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT); - flags = (flags & ~BCDC_DCMD_IF_MASK) | - (ifidx << BCDC_DCMD_IF_SHIFT); - msg->flags = cpu_to_le32(flags); - - if (buf) - memcpy(bcdc->buf, buf, len); - - ret = brcmf_proto_bcdc_msg(drvr); + ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false); if (ret < 0) { brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", ret); @@ -227,19 +221,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); - memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd)); - - msg->cmd = cpu_to_le32(cmd); - msg->len = cpu_to_le32(len); - flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT) | BCDC_DCMD_SET; - flags = (flags & ~BCDC_DCMD_IF_MASK) | - (ifidx << BCDC_DCMD_IF_SHIFT); - msg->flags = cpu_to_le32(flags); - - if (buf) - memcpy(bcdc->buf, buf, len); - - ret = brcmf_proto_bcdc_msg(drvr); + ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true); if (ret < 0) goto done; @@ -369,7 +351,7 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + - sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN; + sizeof(struct brcmf_proto_bcdc_dcmd); return 0; fail: -- cgit v1.1 From 9ecf51c5831b86b367588f2aa50c0b156738b9c6 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Thu, 12 Dec 2013 11:59:01 +0100 Subject: brcmfmac: Fix hex dump for FWIL. The debug function brcmf_dbg_hex_dump API got changed and the information string should preferably contain a \n at the end of the string. Update the FWIL so debug output looks better. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index b72d339..22adbe3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -68,7 +68,7 @@ brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n"); err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); mutex_unlock(&ifp->drvr->proto_block); @@ -86,7 +86,7 @@ brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n"); mutex_unlock(&ifp->drvr->proto_block); @@ -155,7 +155,7 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n"); buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, sizeof(drvr->proto_buf)); @@ -195,7 +195,7 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n"); mutex_unlock(&drvr->proto_block); return err; @@ -278,7 +278,7 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n"); buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, drvr->proto_buf, sizeof(drvr->proto_buf)); @@ -317,7 +317,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, } brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + min_t(uint, len, MAX_HEX_DUMP_LEN), "data\n"); mutex_unlock(&drvr->proto_block); return err; -- cgit v1.1 From 943258b6a3b1fe4b54dd579b9e2e5bec1d9af407 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Thu, 12 Dec 2013 11:59:02 +0100 Subject: brcmfmac: Add definition of new protocol layer msgbuf. A new protocol layer msgbuf will be added in the future. This change makes it possible to select the desired layer by the bus driver. USB and SDIO will select BCDC. At the moment nothing is being done with this information. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 8 ++++++++ drivers/net/wireless/brcm80211/brcmfmac/usb.c | 1 + 3 files changed, 10 insertions(+) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index cf21631..1b333a2 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -1036,6 +1036,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, sdiodev->bus_if = bus_if; bus_if->bus_priv.sdio = sdiodev; + bus_if->proto_type = BRCMF_PROTO_BCDC; dev_set_drvdata(&func->dev, bus_if); dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); sdiodev->dev = &sdiodev->func[1]->dev; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 6a54905..5c12a076 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -24,6 +24,12 @@ enum brcmf_bus_state { BRCMF_BUS_DATA /* Ready for frame transfers */ }; +/* The level of bus communication with the dongle */ +enum brcmf_bus_protocol_type { + BRCMF_PROTO_BCDC, + BRCMF_PROTO_MSGBUF +}; + struct brcmf_bus_dcmd { char *name; char *param; @@ -65,6 +71,7 @@ struct brcmf_bus_ops { * struct brcmf_bus - interface structure between common and bus layer * * @bus_priv: pointer to private bus device. + * @proto_type: protocol type, bcdc or msgbuf * @dev: device pointer of bus device. * @drvr: public driver information. * @state: operational state of the bus interface. @@ -80,6 +87,7 @@ struct brcmf_bus { struct brcmf_sdio_dev *sdio; struct brcmf_usbdev *usb; } bus_priv; + enum brcmf_bus_protocol_type proto_type; struct device *dev; struct brcmf_pub *drvr; enum brcmf_bus_state state; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 51c4de0..c345c32 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -1253,6 +1253,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) bus->ops = &brcmf_usb_bus_ops; bus->chip = bus_pub->devid; bus->chiprev = bus_pub->chiprev; + bus->proto_type = BRCMF_PROTO_BCDC; /* Attach to the common driver interface */ ret = brcmf_attach(dev); -- cgit v1.1 From 7b8a466e7cd36fc2acdba5c22a594e75d9b9f61a Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Thu, 12 Dec 2013 11:59:03 +0100 Subject: brcmfmac: Combine protocol push hdr and bus txdata. For the transmission of data a protocol push hdr is performed followed by a bus txdata call. For the new protocol msgbuf this is not workable. Since they are already "loosely" coupled for bcdc protocol they are combined. This means that txdata will go "through" the protocol layer and a seperate protocol push hdr will not be needed anymore. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 11 ++++++- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 37 ++++++++++------------ drivers/net/wireless/brcm80211/brcmfmac/proto.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/proto.h | 14 ++++---- 4 files changed, 35 insertions(+), 29 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index ee86142..12c27d1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -329,6 +329,15 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, return 0; } +static int +brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset, + struct sk_buff *pktbuf) +{ + brcmf_proto_bcdc_hdrpush(drvr, ifidx, offset, pktbuf); + return brcmf_bus_txdata(drvr->bus_if, pktbuf); +} + + int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { struct brcmf_bcdc *bcdc; @@ -343,10 +352,10 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) goto fail; } - drvr->proto->hdrpush = brcmf_proto_bcdc_hdrpush; drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull; drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd; drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd; + drvr->proto->txdata = brcmf_proto_bcdc_txdata; drvr->proto->pd = bcdc; drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index a593784..7918c10 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -838,7 +838,7 @@ static void brcmf_fws_cleanup(struct brcmf_fws_info *fws, int ifidx) brcmf_fws_hanger_cleanup(fws, matchfn, ifidx); } -static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) +static u8 brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) { struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; u8 *wlh; @@ -887,9 +887,7 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb) if (fillers) memset(wlh, BRCMF_FWS_TYPE_FILLER, fillers); - brcmf_proto_hdrpush(fws->drvr, brcmf_skb_if_flags_get_field(skb, INDEX), - data_offset >> 2, skb); - return 0; + return (u8)(data_offset >> 2); } static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws, @@ -897,10 +895,11 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws, int fifo, bool send_immediately) { struct sk_buff *skb; - struct brcmf_bus *bus; struct brcmf_skbuff_cb *skcb; s32 err; u32 len; + u8 data_offset; + int ifidx; /* check delayedQ and suppressQ in one call using bitmap */ if (brcmu_pktq_mlen(&entry->psq, 3 << (fifo * 2)) == 0) @@ -928,13 +927,11 @@ static bool brcmf_fws_tim_update(struct brcmf_fws_info *fws, skcb->state = BRCMF_FWS_SKBSTATE_TIM; skcb->htod = 0; skcb->htod_seq = 0; - bus = fws->drvr->bus_if; - err = brcmf_fws_hdrpush(fws, skb); - if (err == 0) { - brcmf_fws_unlock(fws); - err = brcmf_bus_txdata(bus, skb); - brcmf_fws_lock(fws); - } + data_offset = brcmf_fws_hdrpush(fws, skb); + ifidx = brcmf_skb_if_flags_get_field(skb, INDEX); + brcmf_fws_unlock(fws); + err = brcmf_proto_txdata(fws->drvr, ifidx, data_offset, skb); + brcmf_fws_lock(fws); if (err) brcmu_pkt_buf_free_skb(skb); return true; @@ -1719,7 +1716,7 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len, return 0; } -static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, +static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, struct sk_buff *p) { struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); @@ -1737,7 +1734,7 @@ static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED; } brcmf_skb_htod_tag_set_field(p, FLAGS, flags); - brcmf_fws_hdrpush(fws, p); + return brcmf_fws_hdrpush(fws, p); } static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, @@ -1805,20 +1802,21 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, { struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb); struct brcmf_fws_mac_descriptor *entry; - struct brcmf_bus *bus = fws->drvr->bus_if; int rc; u8 ifidx; + u8 data_offset; entry = skcb->mac; if (IS_ERR(entry)) return PTR_ERR(entry); - brcmf_fws_precommit_skb(fws, fifo, skb); + data_offset = brcmf_fws_precommit_skb(fws, fifo, skb); entry->transit_count++; if (entry->suppressed) entry->suppr_transit_count++; + ifidx = brcmf_skb_if_flags_get_field(skb, INDEX); brcmf_fws_unlock(fws); - rc = brcmf_bus_txdata(bus, skb); + rc = brcmf_proto_txdata(fws->drvr, ifidx, data_offset, skb); brcmf_fws_lock(fws); brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name, skcb->if_flags, skcb->htod, rc); @@ -1979,10 +1977,9 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker) &skb, true); ifidx = brcmf_skb_if_flags_get_field(skb, INDEX); - brcmf_proto_hdrpush(drvr, ifidx, 0, skb); - /* Use bus module to send data frame */ + /* Use proto layer to send data frame */ brcmf_fws_unlock(fws); - ret = brcmf_bus_txdata(drvr->bus_if, skb); + ret = brcmf_proto_txdata(drvr, ifidx, 0, skb); brcmf_fws_lock(fws); if (ret < 0) brcmf_txfinalize(drvr, skb, false); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/brcm80211/brcmfmac/proto.c index 87eb2bd..b6b4641 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/proto.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.c @@ -39,7 +39,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr) if (brcmf_proto_bcdc_attach(drvr)) goto fail; - if ((proto->hdrpush == NULL) || (proto->hdrpull == NULL) || + if ((proto->txdata == NULL) || (proto->hdrpull == NULL) || (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL)) { brcmf_err("Not all proto handlers have been installed\n"); goto fail; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/brcm80211/brcmfmac/proto.h index 8de1b3b..482fb0b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h @@ -17,14 +17,14 @@ #define BRCMFMAC_PROTO_H struct brcmf_proto { - void (*hdrpush)(struct brcmf_pub *drvr, int ifidx, u8 offset, - struct sk_buff *skb); int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, struct sk_buff *skb); int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); + int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset, + struct sk_buff *skb); void *pd; }; @@ -32,11 +32,6 @@ struct brcmf_proto { int brcmf_proto_attach(struct brcmf_pub *drvr); void brcmf_proto_detach(struct brcmf_pub *drvr); -static inline void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, - u8 offset, struct sk_buff *skb) -{ - drvr->proto->hdrpush(drvr, ifidx, offset, skb); -} static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, struct sk_buff *skb) { @@ -52,6 +47,11 @@ static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx, { return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); } +static inline int brcmf_proto_txdata(struct brcmf_pub *drvr, int ifidx, + u8 offset, struct sk_buff *skb) +{ + return drvr->proto->txdata(drvr, ifidx, offset, skb); +} #endif /* BRCMFMAC_PROTO_H */ -- cgit v1.1 From 82d7f3c10cf41c681e4577bcbc070454e5774960 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:59:04 +0100 Subject: brcmfmac: use consistent function names in dhd_sdio.c Functions in dhd_sdio.c that are called with struct brcmf_sdio instance are renamed consistently with brcmf_sdio_ prefix. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 12 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 346 ++++++++++----------- .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 9 +- 3 files changed, 178 insertions(+), 189 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 1b333a2..a4dae21 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -72,7 +72,7 @@ static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id) sdiodev->irq_en = false; } - brcmf_sdbrcm_isr(sdiodev->bus); + brcmf_sdio_isr(sdiodev->bus); return IRQ_HANDLED; } @@ -84,7 +84,7 @@ static void brcmf_sdiod_ib_irqhandler(struct sdio_func *func) brcmf_dbg(INTR, "IB intr triggered\n"); - brcmf_sdbrcm_isr(sdiodev->bus); + brcmf_sdio_isr(sdiodev->bus); } /* dummy handler for SDIO function 2 interrupt */ @@ -901,7 +901,7 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) sdiodev->bus_if->state = BRCMF_BUS_DOWN; if (sdiodev->bus) { - brcmf_sdbrcm_disconnect(sdiodev->bus); + brcmf_sdio_disconnect(sdiodev->bus); sdiodev->bus = NULL; } @@ -971,7 +971,7 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) sdiodev->max_segment_size = host->max_seg_size; /* try to attach to the target device */ - sdiodev->bus = brcmf_sdbrcm_probe(sdiodev); + sdiodev->bus = brcmf_sdio_probe(sdiodev); if (!sdiodev->bus) { ret = -ENODEV; goto out; @@ -1117,7 +1117,7 @@ static int brcmf_ops_sdio_suspend(struct device *dev) return ret; } - brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); + brcmf_sdio_wd_timer(sdiodev->bus, 0); return ret; } @@ -1127,7 +1127,7 @@ static int brcmf_ops_sdio_resume(struct device *dev) struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; - brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); + brcmf_sdio_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS); atomic_set(&sdiodev->suspend, false); return 0; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 7fff4cc..f3069b4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -556,7 +556,7 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { }; -static const struct firmware *brcmf_sdbrcm_get_fw(struct brcmf_sdio *bus, +static const struct firmware *brcmf_sdio_get_fw(struct brcmf_sdio *bus, enum brcmf_firmware_type type) { const struct firmware *fw; @@ -641,7 +641,7 @@ w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset) } static int -brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on) +brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) { u8 wr_val = 0, rd_val, cmp_val, bmask; int err = 0; @@ -701,7 +701,7 @@ brcmf_sdbrcm_kso_control(struct brcmf_sdio *bus, bool on) #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) /* Turn backplane clock on or off */ -static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) +static int brcmf_sdio_htclk(struct brcmf_sdio *bus, bool on, bool pendok) { int err; u8 clkctl, clkreq, devctl; @@ -823,7 +823,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) } /* Change idle/active SD state */ -static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on) +static int brcmf_sdio_sdclk(struct brcmf_sdio *bus, bool on) { brcmf_dbg(SDIO, "Enter\n"); @@ -836,7 +836,7 @@ static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on) } /* Transition SD and backplane clock readiness */ -static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) +static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) { #ifdef DEBUG uint oldstate = bus->clkstate; @@ -847,7 +847,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) /* Early exit if we're already there */ if (bus->clkstate == target) { if (target == CLK_AVAIL) { - brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); bus->activity = true; } return 0; @@ -857,32 +857,32 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) case CLK_AVAIL: /* Make sure SD clock is available */ if (bus->clkstate == CLK_NONE) - brcmf_sdbrcm_sdclk(bus, true); + brcmf_sdio_sdclk(bus, true); /* Now request HT Avail on the backplane */ - brcmf_sdbrcm_htclk(bus, true, pendok); - brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); + brcmf_sdio_htclk(bus, true, pendok); + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); bus->activity = true; break; case CLK_SDONLY: /* Remove HT request, or bring up SD clock */ if (bus->clkstate == CLK_NONE) - brcmf_sdbrcm_sdclk(bus, true); + brcmf_sdio_sdclk(bus, true); else if (bus->clkstate == CLK_AVAIL) - brcmf_sdbrcm_htclk(bus, false, false); + brcmf_sdio_htclk(bus, false, false); else brcmf_err("request for %d -> %d\n", bus->clkstate, target); - brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); break; case CLK_NONE: /* Make sure to remove HT request */ if (bus->clkstate == CLK_AVAIL) - brcmf_sdbrcm_htclk(bus, false, false); + brcmf_sdio_htclk(bus, false, false); /* Now remove the SD clock */ - brcmf_sdbrcm_sdclk(bus, false); - brcmf_sdbrcm_wd_timer(bus, 0); + brcmf_sdio_sdclk(bus, false); + brcmf_sdio_wd_timer(bus, 0); break; } #ifdef DEBUG @@ -893,7 +893,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) } static int -brcmf_sdbrcm_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) +brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) { int err = 0; brcmf_dbg(TRACE, "Enter\n"); @@ -916,13 +916,13 @@ brcmf_sdbrcm_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && data_ok(bus))) return -EBUSY; - err = brcmf_sdbrcm_kso_control(bus, false); + err = brcmf_sdio_kso_control(bus, false); /* disable watchdog */ if (!err) - brcmf_sdbrcm_wd_timer(bus, 0); + brcmf_sdio_wd_timer(bus, 0); } else { bus->idlecount = 0; - err = brcmf_sdbrcm_kso_control(bus, true); + err = brcmf_sdio_kso_control(bus, true); } if (!err) { /* Change state */ @@ -940,16 +940,16 @@ end: /* control clocks */ if (sleep) { if (!bus->sr_enabled) - brcmf_sdbrcm_clkctl(bus, CLK_NONE, pendok); + brcmf_sdio_clkctl(bus, CLK_NONE, pendok); } else { - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, pendok); + brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); } return err; } -static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) +static u32 brcmf_sdio_hostmail(struct brcmf_sdio *bus) { u32 intstatus = 0; u32 hmb_data; @@ -1025,7 +1025,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) return intstatus; } -static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) +static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) { uint retries = 0; u16 lastrbc; @@ -1085,7 +1085,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) } /* return total length of buffer chain */ -static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus) +static uint brcmf_sdio_glom_len(struct brcmf_sdio *bus) { struct sk_buff *p; uint total; @@ -1096,7 +1096,7 @@ static uint brcmf_sdbrcm_glom_len(struct brcmf_sdio *bus) return total; } -static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) +static void brcmf_sdio_free_glom(struct brcmf_sdio *bus) { struct sk_buff *cur, *next; @@ -1184,7 +1184,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header, if ((u16)(~(len ^ checksum))) { brcmf_err("HW header checksum error\n"); bus->sdcnt.rx_badhdr++; - brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdio_rxfail(bus, false, false); return -EIO; } if (len < SDPCM_HDRLEN) { @@ -1216,7 +1216,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header, type != BRCMF_SDIO_FT_SUPER) { brcmf_err("HW header length too long\n"); bus->sdcnt.rx_toolong++; - brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdio_rxfail(bus, false, false); rd->len = 0; return -EPROTO; } @@ -1235,7 +1235,7 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header, if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { brcmf_err("seq %d: bad data offset\n", rx_seq); bus->sdcnt.rx_badhdr++; - brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdio_rxfail(bus, false, false); rd->len = 0; return -ENXIO; } @@ -1308,7 +1308,7 @@ static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header, trace_brcmf_sdpcm_hdr(SDPCM_TX + !!(bus->txglom), header); } -static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) +static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) { u16 dlen, totlen; u8 *dptr, num = 0; @@ -1388,7 +1388,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } pfirst = pnext = NULL; } else { - brcmf_sdbrcm_free_glom(bus); + brcmf_sdio_free_glom(bus); num = 0; } @@ -1411,7 +1411,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } pfirst = skb_peek(&bus->glom); - dlen = (u16) brcmf_sdbrcm_glom_len(bus); + dlen = (u16) brcmf_sdio_glom_len(bus); /* Do an SDIO read for the superframe. Configurable iovar to * read directly into the chained packet, or allocate a large @@ -1430,12 +1430,12 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) sdio_claim_host(bus->sdiodev->func[1]); if (bus->glomerr++ < 3) { - brcmf_sdbrcm_rxfail(bus, true, true); + brcmf_sdio_rxfail(bus, true, true); } else { bus->glomerr = 0; - brcmf_sdbrcm_rxfail(bus, true, false); + brcmf_sdio_rxfail(bus, true, false); bus->sdcnt.rxglomfail++; - brcmf_sdbrcm_free_glom(bus); + brcmf_sdio_free_glom(bus); } sdio_release_host(bus->sdiodev->func[1]); return 0; @@ -1483,12 +1483,12 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) if (bus->glomerr++ < 3) { /* Restore superframe header space */ skb_push(pfirst, sfdoff); - brcmf_sdbrcm_rxfail(bus, true, true); + brcmf_sdio_rxfail(bus, true, true); } else { bus->glomerr = 0; - brcmf_sdbrcm_rxfail(bus, true, false); + brcmf_sdio_rxfail(bus, true, false); bus->sdcnt.rxglomfail++; - brcmf_sdbrcm_free_glom(bus); + brcmf_sdio_free_glom(bus); } sdio_release_host(bus->sdiodev->func[1]); bus->cur_read.len = 0; @@ -1532,8 +1532,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) return num; } -static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition, - bool *pending) +static int brcmf_sdio_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition, + bool *pending) { DECLARE_WAITQUEUE(wait, current); int timeout = msecs_to_jiffies(DCMD_RESP_TIMEOUT); @@ -1554,7 +1554,7 @@ static int brcmf_sdbrcm_dcmd_resp_wait(struct brcmf_sdio *bus, uint *condition, return timeout; } -static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_sdio *bus) +static int brcmf_sdio_dcmd_resp_wake(struct brcmf_sdio *bus) { if (waitqueue_active(&bus->dcmd_resp_wait)) wake_up_interruptible(&bus->dcmd_resp_wait); @@ -1562,7 +1562,7 @@ static int brcmf_sdbrcm_dcmd_resp_wake(struct brcmf_sdio *bus) return 0; } static void -brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) +brcmf_sdio_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) { uint rdlen, pad; u8 *buf = NULL, *rbuf; @@ -1600,7 +1600,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) if ((rdlen + BRCMF_FIRSTREAD) > bus->sdiodev->bus_if->maxctl) { brcmf_err("%d-byte control read exceeds %d-byte buffer\n", rdlen, bus->sdiodev->bus_if->maxctl); - brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdio_rxfail(bus, false, false); goto done; } @@ -1608,7 +1608,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) brcmf_err("%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", len, len - doff, bus->sdiodev->bus_if->maxctl); bus->sdcnt.rx_toolong++; - brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdio_rxfail(bus, false, false); goto done; } @@ -1621,7 +1621,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) brcmf_err("read %d control bytes failed: %d\n", rdlen, sdret); bus->sdcnt.rxc_errors++; - brcmf_sdbrcm_rxfail(bus, true, true); + brcmf_sdio_rxfail(bus, true, true); goto done; } else memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen); @@ -1646,11 +1646,11 @@ gotpkt: done: /* Awake any waiters */ - brcmf_sdbrcm_dcmd_resp_wake(bus); + brcmf_sdio_dcmd_resp_wake(bus); } /* Pad read to blocksize for efficiency */ -static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) +static void brcmf_sdio_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) { if (bus->roundup && bus->blocksize && *rdlen > bus->blocksize) { *pad = bus->blocksize - (*rdlen % bus->blocksize); @@ -1687,7 +1687,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) u8 cnt; brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", bus->glomd, skb_peek(&bus->glom)); - cnt = brcmf_sdbrcm_rxglom(bus, rd->seq_num); + cnt = brcmf_sdio_rxglom(bus, rd->seq_num); brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); rd->seq_num += cnt - 1; rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; @@ -1705,7 +1705,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) brcmf_err("RXHEADER FAILED: %d\n", ret); bus->sdcnt.rx_hdrfail++; - brcmf_sdbrcm_rxfail(bus, true, true); + brcmf_sdio_rxfail(bus, true, true); sdio_release_host(bus->sdiodev->func[1]); continue; } @@ -1724,9 +1724,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) } if (rd->channel == SDPCM_CONTROL_CHANNEL) { - brcmf_sdbrcm_read_control(bus, bus->rxhdr, - rd->len, - rd->dat_offset); + brcmf_sdio_read_control(bus, bus->rxhdr, + rd->len, + rd->dat_offset); /* prepare the descriptor for the next read */ rd->len = rd->len_nxtfrm << 4; rd->len_nxtfrm = 0; @@ -1740,14 +1740,14 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) head_read = BRCMF_FIRSTREAD; } - brcmf_pad(bus, &pad, &rd->len_left); + brcmf_sdio_pad(bus, &pad, &rd->len_left); pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read + bus->head_align); if (!pkt) { /* Give up on data, request rtx of events */ brcmf_err("brcmu_pkt_buf_get_skb failed\n"); - brcmf_sdbrcm_rxfail(bus, false, + brcmf_sdio_rxfail(bus, false, RETRYCHAN(rd->channel)); sdio_release_host(bus->sdiodev->func[1]); continue; @@ -1764,7 +1764,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd->len, rd->channel, ret); brcmu_pkt_buf_free_skb(pkt); sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_rxfail(bus, true, + brcmf_sdio_rxfail(bus, true, RETRYCHAN(rd->channel)); sdio_release_host(bus->sdiodev->func[1]); continue; @@ -1789,7 +1789,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd->len, roundup(rd_new.len, 16) >> 4); rd->len = 0; - brcmf_sdbrcm_rxfail(bus, true, true); + brcmf_sdio_rxfail(bus, true, true); sdio_release_host(bus->sdiodev->func[1]); brcmu_pkt_buf_free_skb(pkt); continue; @@ -1811,7 +1811,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) /* Force retry w/normal header read */ rd->len = 0; sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_rxfail(bus, false, true); + brcmf_sdio_rxfail(bus, false, true); sdio_release_host(bus->sdiodev->func[1]); brcmu_pkt_buf_free_skb(pkt); continue; @@ -1836,7 +1836,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) brcmf_err("%s: glom superframe w/o " "descriptor!\n", __func__); sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_rxfail(bus, false, false); + brcmf_sdio_rxfail(bus, false, false); sdio_release_host(bus->sdiodev->func[1]); } /* prepare the descriptor for the next read */ @@ -1880,7 +1880,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) } static void -brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) +brcmf_sdio_wait_event_wakeup(struct brcmf_sdio *bus) { if (waitqueue_active(&bus->ctrl_wait)) wake_up_interruptible(&bus->ctrl_wait); @@ -2096,8 +2096,8 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq) /* Writes a HW/SW header into the packet and sends it. */ /* Assumes: (a) header space already there, (b) caller holds lock */ -static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, - uint chan) +static int brcmf_sdio_txpkt(struct brcmf_sdio *bus, struct sk_buff_head *pktq, + uint chan) { int ret; int i; @@ -2148,7 +2148,7 @@ done: return ret; } -static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) +static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes) { struct sk_buff *pkt; struct sk_buff_head pktq; @@ -2182,7 +2182,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) if (i == 0) break; - ret = brcmf_sdbrcm_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL); + ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL); cnt += i; /* In poll mode, need to check for other events */ @@ -2211,7 +2211,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) return cnt; } -static void brcmf_sdbrcm_bus_stop(struct device *dev) +static void brcmf_sdio_bus_stop(struct device *dev) { u32 local_hostintmask; u8 saveclk; @@ -2231,7 +2231,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) sdio_claim_host(bus->sdiodev->func[1]); /* Enable clock for device interrupts */ - brcmf_sdbrcm_bus_sleep(bus, false, false); + brcmf_sdio_bus_sleep(bus, false, false); /* Disable and clear interrupts at the chip level also */ w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); @@ -2260,7 +2260,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) offsetof(struct sdpcmd_regs, intstatus)); /* Turn off the backplane clock (only) */ - brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); + brcmf_sdio_clkctl(bus, CLK_SDONLY, false); sdio_release_host(bus->sdiodev->func[1]); /* Clear the data packet queues */ @@ -2269,20 +2269,20 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) /* Clear any held glomming stuff */ if (bus->glomd) brcmu_pkt_buf_free_skb(bus->glomd); - brcmf_sdbrcm_free_glom(bus); + brcmf_sdio_free_glom(bus); /* Clear rx control and wake any waiters */ spin_lock_bh(&bus->rxctl_lock); bus->rxlen = 0; spin_unlock_bh(&bus->rxctl_lock); - brcmf_sdbrcm_dcmd_resp_wake(bus); + brcmf_sdio_dcmd_resp_wake(bus); /* Reset some F2 state stuff */ bus->rxskip = false; bus->tx_seq = bus->rx_seq = 0; } -static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus) +static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus) { unsigned long flags; @@ -2331,7 +2331,7 @@ static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus) return ret; } -static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) +static void brcmf_sdio_dpc(struct brcmf_sdio *bus) { u32 newstatus = 0; unsigned long intstatus; @@ -2391,7 +2391,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) } /* Make sure backplane clock is on */ - brcmf_sdbrcm_bus_sleep(bus, false, true); + brcmf_sdio_bus_sleep(bus, false, true); /* Pending interrupt indicates new device status */ if (atomic_read(&bus->ipend) > 0) { @@ -2422,7 +2422,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) /* Handle host mailbox indication */ if (intstatus & I_HMB_HOST_INT) { intstatus &= ~I_HMB_HOST_INT; - intstatus |= brcmf_sdbrcm_hostmail(bus); + intstatus |= brcmf_sdio_hostmail(bus); } sdio_release_host(bus->sdiodev->func[1]); @@ -2467,7 +2467,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) set_bit(n, (unsigned long *)&bus->intstatus.counter); } - brcmf_sdbrcm_clrintr(bus); + brcmf_sdio_clrintr(bus); if (data_ok(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { @@ -2508,7 +2508,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) } sdio_release_host(bus->sdiodev->func[1]); bus->ctrl_frame_stat = false; - brcmf_sdbrcm_wait_event_wakeup(bus); + brcmf_sdio_wait_event_wakeup(bus); } /* Send queued frames (limit 1 if rx may still be pending) */ else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) && @@ -2516,7 +2516,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) && data_ok(bus)) { framecnt = bus->rxpending ? min(txlimit, bus->txminmax) : txlimit; - framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt); + framecnt = brcmf_sdio_sendfromq(bus, framecnt); txlimit -= framecnt; } @@ -2538,12 +2538,12 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) bus->activity = false; brcmf_dbg(SDIO, "idle state\n"); sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_bus_sleep(bus, true, false); + brcmf_sdio_bus_sleep(bus, true, false); sdio_release_host(bus->sdiodev->func[1]); } } -static struct pktq *brcmf_sdbrcm_bus_gettxq(struct device *dev) +static struct pktq *brcmf_sdio_bus_gettxq(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; @@ -2552,7 +2552,7 @@ static struct pktq *brcmf_sdbrcm_bus_gettxq(struct device *dev) return &bus->txq; } -static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) +static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) { int ret = -EBADE; uint datalen, prec; @@ -2608,7 +2608,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) #ifdef DEBUG #define CONSOLE_LINE_MAX 192 -static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) +static int brcmf_sdio_readconsole(struct brcmf_sdio *bus) { struct brcmf_console *c = &bus->console; u8 line[CONSOLE_LINE_MAX], ch; @@ -2685,7 +2685,7 @@ break2: } #endif /* DEBUG */ -static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) +static int brcmf_sdio_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) { int i; int ret; @@ -2724,7 +2724,7 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) } static int -brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) +brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) { u8 *frame; u16 len, pad; @@ -2768,7 +2768,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) /* Make sure backplane clock is on */ sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_bus_sleep(bus, false, false); + brcmf_sdio_bus_sleep(bus, false, false); sdio_release_host(bus->sdiodev->func[1]); hd_info.len = (u16)msglen; @@ -2812,7 +2812,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) do { sdio_claim_host(bus->sdiodev->func[1]); - ret = brcmf_tx_frame(bus, frame, len); + ret = brcmf_sdio_tx_frame(bus, frame, len); sdio_release_host(bus->sdiodev->func[1]); } while (ret < 0 && retries++ < TXRETRIES); } @@ -2822,7 +2822,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) bus->activity = false; sdio_claim_host(bus->sdiodev->func[1]); brcmf_dbg(INFO, "idle\n"); - brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); + brcmf_sdio_clkctl(bus, CLK_NONE, true); sdio_release_host(bus->sdiodev->func[1]); } @@ -2856,7 +2856,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, * address of sdpcm_shared structure */ sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_bus_sleep(bus, false, false); + brcmf_sdio_bus_sleep(bus, false, false); rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); sdio_release_host(bus->sdiodev->func[1]); if (rv < 0) @@ -3044,7 +3044,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, return simple_read_from_buffer(data, count, &pos, buf, res); } -static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) +static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) { int error; struct sdpcm_shared sh; @@ -3065,8 +3065,8 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) return 0; } -static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, - size_t count, loff_t *ppos) +static int brcmf_sdio_died_dump(struct brcmf_sdio *bus, char __user *data, + size_t count, loff_t *ppos) { int error = 0; struct sdpcm_shared sh; @@ -3107,7 +3107,7 @@ static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data, struct brcmf_sdio *bus = f->private_data; int res; - res = brcmf_sdbrcm_died_dump(bus, data, count, ppos); + res = brcmf_sdio_died_dump(bus, data, count, ppos); if (res > 0) *ppos += res; return (ssize_t)res; @@ -3132,7 +3132,7 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); } #else -static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) +static int brcmf_sdio_checkdied(struct brcmf_sdio *bus) { return 0; } @@ -3143,7 +3143,7 @@ static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) #endif /* DEBUG */ static int -brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) +brcmf_sdio_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) { int timeleft; uint rxlen = 0; @@ -3156,7 +3156,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) brcmf_dbg(TRACE, "Enter\n"); /* Wait until control frame is available */ - timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); + timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending); spin_lock_bh(&bus->rxctl_lock); rxlen = bus->rxlen; @@ -3173,13 +3173,13 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) rxlen, msglen); } else if (timeleft == 0) { brcmf_err("resumed on timeout\n"); - brcmf_sdbrcm_checkdied(bus); + brcmf_sdio_checkdied(bus); } else if (pending) { brcmf_dbg(CTL, "cancelled\n"); return -ERESTARTSYS; } else { brcmf_dbg(CTL, "resumed for unknown reason?\n"); - brcmf_sdbrcm_checkdied(bus); + brcmf_sdio_checkdied(bus); } if (rxlen) @@ -3190,7 +3190,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) return rxlen ? (int)rxlen : -ETIMEDOUT; } -static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) +static bool brcmf_sdio_download_state(struct brcmf_sdio *bus, bool enter) { struct chip_info *ci = bus->ci; @@ -3215,7 +3215,7 @@ static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) return true; } -static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) +static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) { const struct firmware *fw; int err; @@ -3223,7 +3223,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) int address; int len; - fw = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_BIN); + fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN); if (fw == NULL) return -ENOENT; @@ -3263,8 +3263,8 @@ failure: * by two NULs. */ -static int brcmf_process_nvram_vars(struct brcmf_sdio *bus, - const struct firmware *nv) +static int brcmf_sdio_strip_nvram(struct brcmf_sdio *bus, + const struct firmware *nv) { char *varbuf; char *dp; @@ -3328,44 +3328,48 @@ err: return ret; } -static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) +static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus) { const struct firmware *nv; int ret; - nv = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_NVRAM); + nv = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM); if (nv == NULL) return -ENOENT; - ret = brcmf_process_nvram_vars(bus, nv); + ret = brcmf_sdio_strip_nvram(bus, nv); release_firmware(nv); return ret; } -static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) +static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus) { - int bcmerror = -1; + int bcmerror = -EFAULT; + + + sdio_claim_host(bus->sdiodev->func[1]); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); /* Keep arm in reset */ - if (!brcmf_sdbrcm_download_state(bus, true)) { + if (!brcmf_sdio_download_state(bus, true)) { brcmf_err("error placing ARM core in reset\n"); goto err; } - if (brcmf_sdbrcm_download_code_file(bus)) { + if (brcmf_sdio_download_code_file(bus)) { brcmf_err("dongle image file download failed\n"); goto err; } - if (brcmf_sdbrcm_download_nvram(bus)) { + if (brcmf_sdio_download_nvram(bus)) { brcmf_err("dongle nvram file download failed\n"); goto err; } /* Take arm out of reset */ - if (!brcmf_sdbrcm_download_state(bus, false)) { + if (!brcmf_sdio_download_state(bus, false)) { brcmf_err("error getting out of ARM core reset\n"); goto err; } @@ -3373,10 +3377,12 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) bcmerror = 0; err: + brcmf_sdio_clkctl(bus, CLK_SDONLY, false); + sdio_release_host(bus->sdiodev->func[1]); return bcmerror; } -static bool brcmf_sdbrcm_sr_capable(struct brcmf_sdio *bus) +static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus) { u32 addr, reg; @@ -3395,7 +3401,7 @@ static bool brcmf_sdbrcm_sr_capable(struct brcmf_sdio *bus) return (bool)reg; } -static void brcmf_sdbrcm_sr_init(struct brcmf_sdio *bus) +static void brcmf_sdio_sr_init(struct brcmf_sdio *bus) { int err = 0; u8 val; @@ -3438,7 +3444,7 @@ static void brcmf_sdbrcm_sr_init(struct brcmf_sdio *bus) } /* enable KSO bit */ -static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus) +static int brcmf_sdio_kso_init(struct brcmf_sdio *bus) { u8 val; int err = 0; @@ -3470,25 +3476,7 @@ static int brcmf_sdbrcm_kso_init(struct brcmf_sdio *bus) } -static bool -brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) -{ - bool ret; - - sdio_claim_host(bus->sdiodev->func[1]); - - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - - ret = _brcmf_sdbrcm_download_firmware(bus) == 0; - - brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - - sdio_release_host(bus->sdiodev->func[1]); - - return ret; -} - -static int brcmf_sdbrcm_bus_preinit(struct device *dev) +static int brcmf_sdio_bus_preinit(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; @@ -3547,7 +3535,7 @@ done: return err; } -static int brcmf_sdbrcm_bus_init(struct device *dev) +static int brcmf_sdio_bus_init(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; @@ -3559,8 +3547,9 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) /* try to download image and nvram to the dongle */ if (bus_if->state == BRCMF_BUS_DOWN) { - if (!(brcmf_sdbrcm_download_firmware(bus))) - return -1; + err = brcmf_sdio_download_firmware(bus); + if (err) + return err; } if (!bus->sdiodev->bus_if->drvr) @@ -3568,12 +3557,12 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) /* Start the watchdog timer */ bus->sdcnt.tickcnt = 0; - brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); sdio_claim_host(bus->sdiodev->func[1]); /* Make sure backplane clock is on, needed to generate F2 interrupt */ - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); if (bus->clkstate != CLK_AVAIL) goto exit; @@ -3611,8 +3600,8 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) ret = -ENODEV; } - if (brcmf_sdbrcm_sr_capable(bus)) { - brcmf_sdbrcm_sr_init(bus); + if (brcmf_sdio_sr_capable(bus)) { + brcmf_sdio_sr_init(bus); } else { /* Restore previous clock setting */ brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, @@ -3627,7 +3616,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) /* If we didn't come up, turn off backplane clock */ if (bus_if->state != BRCMF_BUS_DATA) - brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); + brcmf_sdio_clkctl(bus, CLK_NONE, false); exit: sdio_release_host(bus->sdiodev->func[1]); @@ -3635,7 +3624,7 @@ exit: return ret; } -void brcmf_sdbrcm_isr(struct brcmf_sdio *bus) +void brcmf_sdio_isr(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); @@ -3666,7 +3655,7 @@ void brcmf_sdbrcm_isr(struct brcmf_sdio *bus) queue_work(bus->brcmf_wq, &bus->datawork); } -static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) +static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) { #ifdef DEBUG struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); @@ -3722,8 +3711,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->console.count -= bus->console_interval; sdio_claim_host(bus->sdiodev->func[1]); /* Make sure backplane clock is on */ - brcmf_sdbrcm_bus_sleep(bus, false, false); - if (brcmf_sdbrcm_readconsole(bus) < 0) + brcmf_sdio_bus_sleep(bus, false, false); + if (brcmf_sdio_readconsole(bus) < 0) /* stop on error */ bus->console_interval = 0; sdio_release_host(bus->sdiodev->func[1]); @@ -3737,11 +3726,11 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->idlecount = 0; if (bus->activity) { bus->activity = false; - brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); + brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); } else { brcmf_dbg(SDIO, "idle\n"); sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_bus_sleep(bus, true, false); + brcmf_sdio_bus_sleep(bus, true, false); sdio_release_host(bus->sdiodev->func[1]); } } @@ -3756,12 +3745,12 @@ static void brcmf_sdio_dataworker(struct work_struct *work) datawork); while (atomic_read(&bus->dpc_tskcnt)) { - brcmf_sdbrcm_dpc(bus); + brcmf_sdio_dpc(bus); atomic_dec(&bus->dpc_tskcnt); } } -static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus) +static void brcmf_sdio_release_malloc(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); @@ -3770,7 +3759,7 @@ static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus) bus->rxlen = 0; } -static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) +static bool brcmf_sdio_probe_malloc(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); @@ -3787,7 +3776,7 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_sdio *bus) } static bool -brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus) +brcmf_sdio_probe_attach(struct brcmf_sdio *bus) { u8 clkctl = 0; int err = 0; @@ -3824,7 +3813,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus) goto fail; } - if (brcmf_sdbrcm_kso_init(bus)) { + if (brcmf_sdio_kso_init(bus)) { brcmf_err("error enabling KSO\n"); goto fail; } @@ -3899,7 +3888,7 @@ fail: return false; } -static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) +static bool brcmf_sdio_probe_init(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); @@ -3933,7 +3922,7 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) } static int -brcmf_sdbrcm_watchdog_thread(void *data) +brcmf_sdio_watchdog_thread(void *data) { struct brcmf_sdio *bus = (struct brcmf_sdio *)data; @@ -3943,7 +3932,7 @@ brcmf_sdbrcm_watchdog_thread(void *data) if (kthread_should_stop()) break; if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { - brcmf_sdbrcm_bus_watchdog(bus); + brcmf_sdio_bus_watchdog(bus); /* Count the tick for reference */ bus->sdcnt.tickcnt++; } else @@ -3953,7 +3942,7 @@ brcmf_sdbrcm_watchdog_thread(void *data) } static void -brcmf_sdbrcm_watchdog(unsigned long data) +brcmf_sdio_watchdog(unsigned long data) { struct brcmf_sdio *bus = (struct brcmf_sdio *)data; @@ -3966,14 +3955,14 @@ brcmf_sdbrcm_watchdog(unsigned long data) } } -static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) +static void brcmf_sdio_release_dongle(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); if (bus->ci) { sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdio_clkctl(bus, CLK_NONE, false); sdio_release_host(bus->sdiodev->func[1]); brcmf_sdio_chip_detach(&bus->ci); if (bus->vars && bus->varsz) @@ -3985,7 +3974,7 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) } /* Detach and free everything */ -static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) +static void brcmf_sdio_release(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); @@ -3999,11 +3988,11 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) if (bus->sdiodev->bus_if->drvr) { brcmf_detach(bus->sdiodev->dev); - brcmf_sdbrcm_release_dongle(bus); + brcmf_sdio_release_dongle(bus); } brcmu_pkt_buf_free_skb(bus->txglom_sgpad); - brcmf_sdbrcm_release_malloc(bus); + brcmf_sdio_release_malloc(bus); kfree(bus->hdrbuf); kfree(bus); } @@ -4012,16 +4001,16 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) } static struct brcmf_bus_ops brcmf_sdio_bus_ops = { - .stop = brcmf_sdbrcm_bus_stop, - .preinit = brcmf_sdbrcm_bus_preinit, - .init = brcmf_sdbrcm_bus_init, - .txdata = brcmf_sdbrcm_bus_txdata, - .txctl = brcmf_sdbrcm_bus_txctl, - .rxctl = brcmf_sdbrcm_bus_rxctl, - .gettxq = brcmf_sdbrcm_bus_gettxq, + .stop = brcmf_sdio_bus_stop, + .preinit = brcmf_sdio_bus_preinit, + .init = brcmf_sdio_bus_init, + .txdata = brcmf_sdio_bus_txdata, + .txctl = brcmf_sdio_bus_txctl, + .rxctl = brcmf_sdio_bus_rxctl, + .gettxq = brcmf_sdio_bus_gettxq, }; -struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) +struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_sdio *bus; @@ -4061,8 +4050,8 @@ struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) } /* attempt to attach to the dongle */ - if (!(brcmf_sdbrcm_probe_attach(bus))) { - brcmf_err("brcmf_sdbrcm_probe_attach failed\n"); + if (!(brcmf_sdio_probe_attach(bus))) { + brcmf_err("brcmf_sdio_probe_attach failed\n"); goto fail; } @@ -4074,11 +4063,11 @@ struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) /* Set up the watchdog timer */ init_timer(&bus->timer); bus->timer.data = (unsigned long)bus; - bus->timer.function = brcmf_sdbrcm_watchdog; + bus->timer.function = brcmf_sdio_watchdog; /* Initialize watchdog thread */ init_completion(&bus->watchdog_wait); - bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, + bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread, bus, "brcmf_watchdog"); if (IS_ERR(bus->watchdog_tsk)) { pr_warn("brcmf_watchdog thread failed to start\n"); @@ -4104,13 +4093,13 @@ struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) } /* Allocate buffers */ - if (!(brcmf_sdbrcm_probe_malloc(bus))) { - brcmf_err("brcmf_sdbrcm_probe_malloc failed\n"); + if (!(brcmf_sdio_probe_malloc(bus))) { + brcmf_err("brcmf_sdio_probe_malloc failed\n"); goto fail; } - if (!(brcmf_sdbrcm_probe_init(bus))) { - brcmf_err("brcmf_sdbrcm_probe_init failed\n"); + if (!(brcmf_sdio_probe_init(bus))) { + brcmf_err("brcmf_sdio_probe_init failed\n"); goto fail; } @@ -4127,21 +4116,20 @@ struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev) return bus; fail: - brcmf_sdbrcm_release(bus); + brcmf_sdio_release(bus); return NULL; } -void brcmf_sdbrcm_disconnect(struct brcmf_sdio *bus) +void brcmf_sdio_disconnect(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); - brcmf_sdbrcm_release(bus); + brcmf_sdio_release(bus); brcmf_dbg(TRACE, "Disconnected\n"); } -void -brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick) +void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick) { /* Totally stop the timer */ if (!wdtick && bus->wd_timer_valid) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 4c70cf2..e28498e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -235,9 +235,10 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, /* Issue an abort to the specified function */ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); -struct brcmf_sdio *brcmf_sdbrcm_probe(struct brcmf_sdio_dev *sdiodev); -void brcmf_sdbrcm_disconnect(struct brcmf_sdio *bus); -void brcmf_sdbrcm_isr(struct brcmf_sdio *bus); -void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); +struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); +void brcmf_sdio_disconnect(struct brcmf_sdio *bus); +void brcmf_sdio_isr(struct brcmf_sdio *bus); + +void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); #endif /* _BRCM_SDH_H_ */ -- cgit v1.1 From 9fbe2a6dc71d85e166eea43842a55af3d62a4d7b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:59:05 +0100 Subject: brcmfmac: remove brcmf_sdio_disconnect() function Instead of calling brcmf_sdio_disconnect() expose brcmf_sdio_remove() and call it directly. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 51 +++++++++------------- .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 2 +- 3 files changed, 23 insertions(+), 32 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index a4dae21..7550f9f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -901,7 +901,7 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) sdiodev->bus_if->state = BRCMF_BUS_DOWN; if (sdiodev->bus) { - brcmf_sdio_disconnect(sdiodev->bus); + brcmf_sdio_remove(sdiodev->bus); sdiodev->bus = NULL; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f3069b4..f214510 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3973,33 +3973,6 @@ static void brcmf_sdio_release_dongle(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Disconnected\n"); } -/* Detach and free everything */ -static void brcmf_sdio_release(struct brcmf_sdio *bus) -{ - brcmf_dbg(TRACE, "Enter\n"); - - if (bus) { - /* De-register interrupt handler */ - brcmf_sdiod_intr_unregister(bus->sdiodev); - - cancel_work_sync(&bus->datawork); - if (bus->brcmf_wq) - destroy_workqueue(bus->brcmf_wq); - - if (bus->sdiodev->bus_if->drvr) { - brcmf_detach(bus->sdiodev->dev); - brcmf_sdio_release_dongle(bus); - } - - brcmu_pkt_buf_free_skb(bus->txglom_sgpad); - brcmf_sdio_release_malloc(bus); - kfree(bus->hdrbuf); - kfree(bus); - } - - brcmf_dbg(TRACE, "Disconnected\n"); -} - static struct brcmf_bus_ops brcmf_sdio_bus_ops = { .stop = brcmf_sdio_bus_stop, .preinit = brcmf_sdio_bus_preinit, @@ -4116,15 +4089,33 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) return bus; fail: - brcmf_sdio_release(bus); + brcmf_sdio_remove(bus); return NULL; } -void brcmf_sdio_disconnect(struct brcmf_sdio *bus) +/* Detach and free everything */ +void brcmf_sdio_remove(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); - brcmf_sdio_release(bus); + if (bus) { + /* De-register interrupt handler */ + brcmf_sdiod_intr_unregister(bus->sdiodev); + + cancel_work_sync(&bus->datawork); + if (bus->brcmf_wq) + destroy_workqueue(bus->brcmf_wq); + + if (bus->sdiodev->bus_if->drvr) { + brcmf_detach(bus->sdiodev->dev); + brcmf_sdio_release_dongle(bus); + } + + brcmu_pkt_buf_free_skb(bus->txglom_sgpad); + brcmf_sdio_release_malloc(bus); + kfree(bus->hdrbuf); + kfree(bus); + } brcmf_dbg(TRACE, "Disconnected\n"); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index e28498e..a0981b3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -236,7 +236,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); -void brcmf_sdio_disconnect(struct brcmf_sdio *bus); +void brcmf_sdio_remove(struct brcmf_sdio *bus); void brcmf_sdio_isr(struct brcmf_sdio *bus); void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick); -- cgit v1.1 From 36c4e7e4aa0605cd175ee4b953eaced7a00157f4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 12 Dec 2013 11:59:06 +0100 Subject: brcmfmac: clarify struct brcmf_sdio_dev::func[0] reference The struct brcmf_sdio_dev contains array of sdio functions that are used in the driver. However, during probe func[0] entry was assigned to the function 1 reference. This was corrected upon doing the actual I/O access. This patch makes it more clear by creating the func[0] entry properly and use it as is during I/O access. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 36 +++++++++++------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 7550f9f..2b5cde6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -197,32 +197,21 @@ int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) return 0; } -static inline int brcmf_sdiod_f0_write_byte(struct brcmf_sdio_dev *sdiodev, - uint regaddr, u8 *byte) +static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, + uint regaddr, u8 byte) { - struct sdio_func *sdfunc = sdiodev->func[0]; int err_ret; /* * Can only directly write to some F0 registers. - * Handle F2 enable/disable and Abort command + * Handle CCCR_IENx and CCCR_ABORT command * as a special case. */ if ((regaddr == SDIO_CCCR_ABORT) || - (regaddr == SDIO_CCCR_IENx)) { - sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), - GFP_KERNEL); - if (!sdfunc) - return -ENOMEM; - sdfunc->num = 0; - sdio_writeb(sdfunc, *byte, regaddr, &err_ret); - kfree(sdfunc); - } else if (regaddr < 0xF0) { - brcmf_err("F0 Wr:0x%02x: write disallowed\n", regaddr); - err_ret = -EPERM; - } else { - sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); - } + (regaddr == SDIO_CCCR_IENx)) + sdio_writeb(func, byte, regaddr, &err_ret); + else + sdio_f0_writeb(func, byte, regaddr, &err_ret); return err_ret; } @@ -240,7 +229,8 @@ static int brcmf_sdiod_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, if (rw && func == 0) { /* handle F0 separately */ - err_ret = brcmf_sdiod_f0_write_byte(sdiodev, regaddr, byte); + err_ret = brcmf_sdiod_f0_writeb(sdiodev->func[func], + regaddr, *byte); } else { if (rw) /* CMD52 Write */ sdio_writeb(sdiodev->func[func], *byte, regaddr, @@ -1030,7 +1020,11 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, return -ENOMEM; } - sdiodev->func[0] = func->card->sdio_func[0]; + /* store refs to functions used. mmc_card does + * not hold the F0 function pointer. + */ + sdiodev->func[0] = kmemdup(func, sizeof(*func), GFP_KERNEL); + sdiodev->func[0]->num = 0; sdiodev->func[1] = func->card->sdio_func[0]; sdiodev->func[2] = func; @@ -1060,6 +1054,7 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, fail: dev_set_drvdata(&func->dev, NULL); dev_set_drvdata(&sdiodev->func[1]->dev, NULL); + kfree(sdiodev->func[0]); kfree(sdiodev); kfree(bus_if); return err; @@ -1087,6 +1082,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func) dev_set_drvdata(&sdiodev->func[2]->dev, NULL); kfree(bus_if); + kfree(sdiodev->func[0]); kfree(sdiodev); } -- cgit v1.1 From fa9ffc745610f31c6bc136d5a6a1782e00870e72 Mon Sep 17 00:00:00 2001 From: Kyeyoon Park Date: Mon, 16 Dec 2013 23:01:30 -0800 Subject: cfg80211: Add support for QoS mapping This allows QoS mapping from external networks to be implemented as defined in IEEE Std 802.11-2012, 10.24.9. APs can use this to advertise DSCP ranges and exceptions for mapping frames to a specific UP over Wi-Fi. The payload of the QoS Map Set element (IEEE Std 802.11-2012, 8.4.2.97) is sent to the driver through the new NL80211_ATTR_QOS_MAP attribute to configure the local behavior either on the AP (based on local configuration) or on a station (based on information received from the AP). Signed-off-by: Kyeyoon Park Signed-off-by: Jouni Malinen Signed-off-by: Johannes Berg --- drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index e9bdfdb..4f80e12 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -1873,7 +1873,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); /* determine the priority */ if (!skb->priority) - skb->priority = cfg80211_classify8021d(skb); + skb->priority = cfg80211_classify8021d(skb, NULL); drvr->tx_multicast += !!multicast; if (pae) -- cgit v1.1 From 692e5167b4487c96123c2de4c8d9577d50606112 Mon Sep 17 00:00:00 2001 From: dingtianhong Date: Thu, 26 Dec 2013 19:41:34 +0800 Subject: wireless: slight optimization of addr compare Use possibly more efficient ether_addr_equal or ether_addr_equal_unaligned instead of memcmp. Cc: John W. Linville Cc: linux-wireless@vger.kernel.org Cc: netdev@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Weilong Chen Signed-off-by: Ding Tianhong Signed-off-by: David S. Miller --- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index d318036..185af8a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -1243,7 +1243,7 @@ bool brcmf_p2p_scan_finding_common_channel(struct brcmf_cfg80211_info *cfg, IEEE80211_P2P_ATTR_DEVICE_ID, p2p_dev_addr, sizeof(p2p_dev_addr)); if ((err >= 0) && - (!memcmp(p2p_dev_addr, afx_hdl->tx_dst_addr, ETH_ALEN))) { + (ether_addr_equal(p2p_dev_addr, afx_hdl->tx_dst_addr))) { if (!bi->ctl_ch) { ch.chspec = le16_to_cpu(bi->chanspec); cfg->d11inf.decchspec(&ch); @@ -1380,8 +1380,7 @@ int brcmf_p2p_notify_action_frame_rx(struct brcmf_if *ifp, (brcmf_p2p_gon_req_collision(p2p, (u8 *)e->addr))) { if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && - (memcmp(afx_hdl->tx_dst_addr, e->addr, - ETH_ALEN) == 0)) { + (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { afx_hdl->peer_chan = ch.chnum; brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", afx_hdl->peer_chan); @@ -1865,7 +1864,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp, cfg->d11inf.decchspec(&ch); if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && - (memcmp(afx_hdl->tx_dst_addr, e->addr, ETH_ALEN) == 0)) { + (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { afx_hdl->peer_chan = ch.chnum; brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", afx_hdl->peer_chan); -- cgit v1.1 From 4ad77ac92d533af14e6eab0d8bd020e4dd731a0f Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 23 Dec 2013 13:55:03 -0800 Subject: net: wireless: brcm80211: Drop debug version with build date/time The kernel already has this information, and individual drivers shouldn't duplicate that. This also eliminates the use of __DATE__ and __TIME__, which make the build non-deterministic. Signed-off-by: Josh Triplett Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 548dbb5..7b6bdd1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -32,15 +32,8 @@ #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" -#ifdef DEBUG -static const char brcmf_version[] = - "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " - __DATE__ " at " __TIME__; -#else static const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR; -#endif - bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec) -- cgit v1.1 From 71c60cf2e9db4936340e1ef021d42d3e810230c8 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:36 +0100 Subject: brcmfmac: rework SDIO register access functions The logic in the SDIO register access functions was hard to read and contained a lot of conditional code path. This rework attempts to clean it up. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 227 +++++++++------------ .../net/wireless/brcm80211/brcmfmac/sdio_host.h | 1 - 2 files changed, 96 insertions(+), 132 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 2b5cde6..07015e1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -216,94 +216,104 @@ static inline int brcmf_sdiod_f0_writeb(struct sdio_func *func, return err_ret; } -static int brcmf_sdiod_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, - uint func, uint regaddr, u8 *byte) +static int brcmf_sdiod_request_data(struct brcmf_sdio_dev *sdiodev, u8 fn, + u32 addr, u8 regsz, void *data, bool write) { - int err_ret; + struct sdio_func *func; + int ret; - brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); + brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", + write, fn, addr, regsz); - brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait); + brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); if (brcmf_sdiod_pm_resume_error(sdiodev)) return -EIO; - if (rw && func == 0) { - /* handle F0 separately */ - err_ret = brcmf_sdiod_f0_writeb(sdiodev->func[func], - regaddr, *byte); - } else { - if (rw) /* CMD52 Write */ - sdio_writeb(sdiodev->func[func], *byte, regaddr, - &err_ret); - else if (func == 0) { - *byte = sdio_f0_readb(sdiodev->func[func], regaddr, - &err_ret); + /* only allow byte access on F0 */ + if (WARN_ON(regsz > 1 && !fn)) + return -EINVAL; + func = sdiodev->func[fn]; + + switch (regsz) { + case sizeof(u8): + if (write) { + if (fn) + sdio_writeb(func, *(u8 *)data, addr, &ret); + else + ret = brcmf_sdiod_f0_writeb(func, addr, + *(u8 *)data); } else { - *byte = sdio_readb(sdiodev->func[func], regaddr, - &err_ret); + if (fn) + *(u8 *)data = sdio_readb(func, addr, &ret); + else + *(u8 *)data = sdio_f0_readb(func, addr, &ret); } + break; + case sizeof(u16): + if (write) + sdio_writew(func, *(u16 *)data, addr, &ret); + else + *(u16 *)data = sdio_readw(func, addr, &ret); + break; + case sizeof(u32): + if (write) + sdio_writel(func, *(u32 *)data, addr, &ret); + else + *(u32 *)data = sdio_readl(func, addr, &ret); + break; + default: + brcmf_err("invalid size: %d\n", regsz); + break; } - if (err_ret) { + if (ret) { /* * SleepCSR register access can fail when * waking up the device so reduce this noise * in the logs. */ - if (regaddr != SBSDIO_FUNC1_SLEEPCSR) - brcmf_err("Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "write" : "read", func, regaddr, *byte, - err_ret); + if (addr != SBSDIO_FUNC1_SLEEPCSR) + brcmf_err("failed to %s data F%d@0x%05x, err: %d\n", + write ? "write" : "read", fn, addr, ret); else - brcmf_dbg(SDIO, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", - rw ? "write" : "read", func, regaddr, *byte, - err_ret); + brcmf_dbg(SDIO, "failed to %s data F%d@0x%05x, err: %d\n", + write ? "write" : "read", fn, addr, ret); } - return err_ret; + return ret; } -static int brcmf_sdiod_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, - uint func, uint addr, u32 *word, - uint nbytes) +static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, + u8 regsz, void *data, bool write) { - int err_ret = -EIO; - - if (func == 0) { - brcmf_err("Only CMD52 allowed to F0\n"); - return -EINVAL; - } - - brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - rw, func, addr, nbytes); + u8 func_num; + s32 retry = 0; + int ret; - brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); - if (brcmf_sdiod_pm_resume_error(sdiodev)) - return -EIO; + /* + * figure out how to read the register based on address range + * 0x00 ~ 0x7FF: function 0 CCCR and FBR + * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers + * The rest: function 1 silicon backplane core registers + */ + if ((addr & ~REG_F0_REG_MASK) == 0) + func_num = SDIO_FUNC_0; + else + func_num = SDIO_FUNC_1; - if (rw) { /* CMD52 Write */ - if (nbytes == 4) - sdio_writel(sdiodev->func[func], *word, addr, - &err_ret); - else if (nbytes == 2) - sdio_writew(sdiodev->func[func], (*word & 0xFFFF), - addr, &err_ret); - else - brcmf_err("Invalid nbytes: %d\n", nbytes); - } else { /* CMD52 Read */ - if (nbytes == 4) - *word = sdio_readl(sdiodev->func[func], addr, &err_ret); - else if (nbytes == 2) - *word = sdio_readw(sdiodev->func[func], addr, - &err_ret) & 0xFFFF; - else - brcmf_err("Invalid nbytes: %d\n", nbytes); - } + do { + if (!write) + memset(data, 0, regsz); + /* for retry wait for 1 ms till bus get settled down */ + if (retry) + usleep_range(1000, 2000); + ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz, + data, write); + } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); - if (err_ret) - brcmf_err("Failed to %s word, Err: 0x%08x\n", - rw ? "write" : "read", err_ret); + if (ret != 0) + brcmf_err("failed with %d\n", ret); - return err_ret; + return ret; } static int @@ -311,24 +321,17 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) { int err = 0, i; u8 addr[3]; - s32 retry; addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; for (i = 0; i < 3; i++) { - retry = 0; - do { - if (retry) - usleep_range(1000, 2000); - err = brcmf_sdiod_request_byte(sdiodev, SDIOH_WRITE, - SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW + i, - &addr[i]); - } while (err != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); - + err = brcmf_sdiod_regrw_helper(sdiodev, + SBSDIO_FUNC1_SBADDRLOW + i, + sizeof(u8), &addr[i], true); if (err) { - brcmf_err("failed at addr:0x%0x\n", + brcmf_err("failed at addr: 0x%0x\n", SBSDIO_FUNC1_SBADDRLOW + i); break; } @@ -359,61 +362,14 @@ brcmf_sdiod_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr) return 0; } -static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - void *data, bool write) -{ - u8 func_num, reg_size; - s32 retry = 0; - int ret; - - /* - * figure out how to read the register based on address range - * 0x00 ~ 0x7FF: function 0 CCCR and FBR - * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers - * The rest: function 1 silicon backplane core registers - */ - if ((addr & ~REG_F0_REG_MASK) == 0) { - func_num = SDIO_FUNC_0; - reg_size = 1; - } else if ((addr & ~REG_F1_MISC_MASK) == 0) { - func_num = SDIO_FUNC_1; - reg_size = 1; - } else { - func_num = SDIO_FUNC_1; - reg_size = 4; - - ret = brcmf_sdiod_addrprep(sdiodev, reg_size, &addr); - if (ret) - goto done; - } - - do { - if (!write) - memset(data, 0, reg_size); - if (retry) /* wait for 1 ms till bus get settled down */ - usleep_range(1000, 2000); - if (reg_size == 1) - ret = brcmf_sdiod_request_byte(sdiodev, write, - func_num, addr, data); - else - ret = brcmf_sdiod_request_word(sdiodev, write, - func_num, addr, data, 4); - } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); - -done: - if (ret != 0) - brcmf_err("failed with %d\n", ret); - - return ret; -} - u8 brcmf_sdiod_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) { u8 data; int retval; brcmf_dbg(SDIO, "addr:0x%08x\n", addr); - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, false); + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, + false); brcmf_dbg(SDIO, "data:0x%02x\n", data); if (ret) @@ -428,9 +384,14 @@ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) int retval; brcmf_dbg(SDIO, "addr:0x%08x\n", addr); - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, false); + retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); + if (retval) + goto done; + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, + false); brcmf_dbg(SDIO, "data:0x%08x\n", data); +done: if (ret) *ret = retval; @@ -443,8 +404,8 @@ void brcmf_sdiod_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, int retval; brcmf_dbg(SDIO, "addr:0x%08x, data:0x%02x\n", addr, data); - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, true); - + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, + true); if (ret) *ret = retval; } @@ -455,8 +416,13 @@ void brcmf_sdiod_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, int retval; brcmf_dbg(SDIO, "addr:0x%08x, data:0x%08x\n", addr, data); - retval = brcmf_sdiod_regrw_helper(sdiodev, addr, &data, true); + retval = brcmf_sdiod_addrprep(sdiodev, sizeof(data), &addr); + if (retval) + goto done; + retval = brcmf_sdiod_regrw_helper(sdiodev, addr, sizeof(data), &data, + true); +done: if (ret) *ret = retval; } @@ -879,8 +845,8 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) brcmf_dbg(SDIO, "Enter\n"); /* issue abort cmd52 command through F0 */ - brcmf_sdiod_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, - SDIO_CCCR_ABORT, &t_func); + brcmf_sdiod_request_data(sdiodev, SDIO_FUNC_0, SDIO_CCCR_ABORT, + sizeof(t_func), &t_func, true); brcmf_dbg(SDIO, "Exit\n"); return 0; @@ -1037,7 +1003,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, sdiodev->pdata = brcmfmac_sdio_pdata; atomic_set(&sdiodev->suspend, false); - init_waitqueue_head(&sdiodev->request_byte_wait); init_waitqueue_head(&sdiodev->request_word_wait); init_waitqueue_head(&sdiodev->request_buffer_wait); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index a0981b3..092e9c8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -167,7 +167,6 @@ struct brcmf_sdio_dev { u32 sbwad; /* Save backplane window address */ struct brcmf_sdio *bus; atomic_t suspend; /* suspend flag */ - wait_queue_head_t request_byte_wait; wait_queue_head_t request_word_wait; wait_queue_head_t request_buffer_wait; struct device *dev; -- cgit v1.1 From 75b39dd2408833ed4eaa16fe76473d1391ca49ee Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Mon, 6 Jan 2014 12:40:37 +0100 Subject: brcmfmac: Remove some obsolete definitions and variables. Reviewed-by: Arend Van Spriel Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 2 -- drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 252024b..e299657 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -21,8 +21,6 @@ #ifndef _BRCMF_H_ #define _BRCMF_H_ -#define BRCMF_VERSION_STR "4.218.248.5" - #include "fweh.h" #define TOE_TX_CSUM_OL 0x00000001 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 7b6bdd1..6a8983a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -32,8 +32,6 @@ #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" -static const char brcmf_version[] = - "Dongle Host Driver, version " BRCMF_VERSION_STR; bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec) -- cgit v1.1 From d453399229cefff985391f079066ac5a84955537 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Mon, 6 Jan 2014 12:40:38 +0100 Subject: brcmfmac: Limit control message length from host to device. An control request or set message length is restricted to ETH frame length for the buffer from host to device. This is limitation is imposed by the firmware. Reviewed-by: Arend Van Spriel Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcdc.c | 10 +++++----- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c index 12c27d1..c229210 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c @@ -41,9 +41,6 @@ struct brcmf_proto_bcdc_dcmd { __le32 status; /* status code returned from the device */ }; -/* Max valid buffer size that can be sent to the dongle */ -#define BCDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) - /* BCDC flag definitions */ #define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */ #define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */ @@ -133,9 +130,12 @@ brcmf_proto_bcdc_msg(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, if (buf) memcpy(bcdc->buf, buf, len); + len += sizeof(*msg); + if (len > BRCMF_TX_IOCTL_MAX_MSG_SIZE) + len = BRCMF_TX_IOCTL_MAX_MSG_SIZE; + /* Send request */ - return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, - len + sizeof(struct brcmf_proto_bcdc_dcmd)); + return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len); } static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index e299657..939d6b1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -37,6 +37,11 @@ #define BRCMF_DCMD_MEDLEN 1536 #define BRCMF_DCMD_MAXLEN 8192 +/* IOCTL from host to device are limited in lenght. A device can only handle + * ethernet frame size. This limitation is to be applied by protocol layer. + */ +#define BRCMF_TX_IOCTL_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) + #define BRCMF_AMPDU_RX_REORDER_MAXFLOWS 256 /* Length of firmware version string stored for -- cgit v1.1 From bfad4a048c44c37ce4c606ad3f6a745607d515e9 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:39 +0100 Subject: brcmfmac: cleanup helper functions in sdio remove path Two helper functions in the sdio remove path were very thin and only used once. So its code is moved to the calling function. Reviewed-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 39 ++++++---------------- 1 file changed, 10 insertions(+), 29 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f214510..27fbcbf 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3750,15 +3750,6 @@ static void brcmf_sdio_dataworker(struct work_struct *work) } } -static void brcmf_sdio_release_malloc(struct brcmf_sdio *bus) -{ - brcmf_dbg(TRACE, "Enter\n"); - - kfree(bus->rxbuf); - bus->rxctl = bus->rxbuf = NULL; - bus->rxlen = 0; -} - static bool brcmf_sdio_probe_malloc(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); @@ -3955,24 +3946,6 @@ brcmf_sdio_watchdog(unsigned long data) } } -static void brcmf_sdio_release_dongle(struct brcmf_sdio *bus) -{ - brcmf_dbg(TRACE, "Enter\n"); - - if (bus->ci) { - sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdio_clkctl(bus, CLK_AVAIL, false); - brcmf_sdio_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); - brcmf_sdio_chip_detach(&bus->ci); - if (bus->vars && bus->varsz) - kfree(bus->vars); - bus->vars = NULL; - } - - brcmf_dbg(TRACE, "Disconnected\n"); -} - static struct brcmf_bus_ops brcmf_sdio_bus_ops = { .stop = brcmf_sdio_bus_stop, .preinit = brcmf_sdio_bus_preinit, @@ -4108,12 +4081,20 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) if (bus->sdiodev->bus_if->drvr) { brcmf_detach(bus->sdiodev->dev); - brcmf_sdio_release_dongle(bus); + } + + if (bus->ci) { + sdio_claim_host(bus->sdiodev->func[1]); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + brcmf_sdio_clkctl(bus, CLK_NONE, false); + sdio_release_host(bus->sdiodev->func[1]); + brcmf_sdio_chip_detach(&bus->ci); } brcmu_pkt_buf_free_skb(bus->txglom_sgpad); - brcmf_sdio_release_malloc(bus); + kfree(bus->rxbuf); kfree(bus->hdrbuf); + kfree(bus->vars); kfree(bus); } -- cgit v1.1 From fad132285081c1c37b57be5ff74e23edbf9b1864 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:40 +0100 Subject: brcmfmac: cleanup helper functions in sdio probe path Moving code from helper functions to the calling function as it makes code easier to read. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 90 ++++++++-------------- 1 file changed, 34 insertions(+), 56 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 27fbcbf..270cf9b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3750,22 +3750,6 @@ static void brcmf_sdio_dataworker(struct work_struct *work) } } -static bool brcmf_sdio_probe_malloc(struct brcmf_sdio *bus) -{ - brcmf_dbg(TRACE, "Enter\n"); - - if (bus->sdiodev->bus_if->maxctl) { - bus->rxblen = - roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), - ALIGNMENT) + bus->head_align; - bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); - if (!(bus->rxbuf)) - return false; - } - - return true; -} - static bool brcmf_sdio_probe_attach(struct brcmf_sdio *bus) { @@ -3879,39 +3863,6 @@ fail: return false; } -static bool brcmf_sdio_probe_init(struct brcmf_sdio *bus) -{ - brcmf_dbg(TRACE, "Enter\n"); - - sdio_claim_host(bus->sdiodev->func[1]); - - /* Disable F2 to clear any intermediate frame state on the dongle */ - sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); - - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; - bus->rxflow = false; - - /* Done with backplane-dependent accesses, can drop clock... */ - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); - - sdio_release_host(bus->sdiodev->func[1]); - - /* ...and initialize clock/power states */ - bus->clkstate = CLK_SDONLY; - bus->idletime = BRCMF_IDLE_INTERVAL; - bus->idleclock = BRCMF_IDLE_ACTIVE; - - /* Query the F2 block size, set roundup accordingly */ - bus->blocksize = bus->sdiodev->func[2]->cur_blksize; - bus->roundup = min(max_roundup, bus->blocksize); - - /* SR state */ - bus->sleeping = false; - bus->sr_enabled = false; - - return true; -} - static int brcmf_sdio_watchdog_thread(void *data) { @@ -4039,15 +3990,42 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) } /* Allocate buffers */ - if (!(brcmf_sdio_probe_malloc(bus))) { - brcmf_err("brcmf_sdio_probe_malloc failed\n"); - goto fail; + if (bus->sdiodev->bus_if->maxctl) { + bus->rxblen = + roundup((bus->sdiodev->bus_if->maxctl + SDPCM_HDRLEN), + ALIGNMENT) + bus->head_align; + bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); + if (!(bus->rxbuf)) { + brcmf_err("rxbuf allocation failed\n"); + goto fail; + } } - if (!(brcmf_sdio_probe_init(bus))) { - brcmf_err("brcmf_sdio_probe_init failed\n"); - goto fail; - } + sdio_claim_host(bus->sdiodev->func[1]); + + /* Disable F2 to clear any intermediate frame state on the dongle */ + sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); + + bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; + bus->rxflow = false; + + /* Done with backplane-dependent accesses, can drop clock... */ + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); + + sdio_release_host(bus->sdiodev->func[1]); + + /* ...and initialize clock/power states */ + bus->clkstate = CLK_SDONLY; + bus->idletime = BRCMF_IDLE_INTERVAL; + bus->idleclock = BRCMF_IDLE_ACTIVE; + + /* Query the F2 block size, set roundup accordingly */ + bus->blocksize = bus->sdiodev->func[2]->cur_blksize; + bus->roundup = min(max_roundup, bus->blocksize); + + /* SR state */ + bus->sleeping = false; + bus->sr_enabled = false; brcmf_sdio_debugfs_create(bus); brcmf_dbg(INFO, "completed!!\n"); -- cgit v1.1 From 2375d9701bb2f524ade9860fb4f7bc82c76c661a Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:41 +0100 Subject: brcmfmac: correct reporting HT40 support in wiphy htcap Using 'iw phy' only showed HT20 support in the HT capabilities info. This patch determines support for HT40 using a firmware query that is supposed to work for all supported devices. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 120 +++++++++++++-------- 1 file changed, 77 insertions(+), 43 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 3966fe0..a7c1afe 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -5087,7 +5087,8 @@ dongle_scantime_out: } -static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) +static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, + u32 bw_cap[]) { struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct ieee80211_channel *band_chan_arr; @@ -5100,7 +5101,6 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) enum ieee80211_band band; u32 channel; u32 *n_cnt; - bool ht40_allowed; u32 index; u32 ht40_flag; bool update; @@ -5133,18 +5133,17 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) array_size = ARRAY_SIZE(__wl_2ghz_channels); n_cnt = &__wl_band_2ghz.n_channels; band = IEEE80211_BAND_2GHZ; - ht40_allowed = (bw_cap == WLC_N_BW_40ALL); } else if (ch.band == BRCMU_CHAN_BAND_5G) { band_chan_arr = __wl_5ghz_a_channels; array_size = ARRAY_SIZE(__wl_5ghz_a_channels); n_cnt = &__wl_band_5ghz_a.n_channels; band = IEEE80211_BAND_5GHZ; - ht40_allowed = !(bw_cap == WLC_N_BW_20ALL); } else { - brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec); + brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); continue; } - if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40) + if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) && + ch.bw == BRCMU_CHAN_BW_40) continue; update = false; for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { @@ -5162,7 +5161,10 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap) ieee80211_channel_to_frequency(ch.chnum, band); band_chan_arr[index].hw_value = ch.chnum; - if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) { + brcmf_err("channel %d: f=%d bw=%d sb=%d\n", + ch.chnum, band_chan_arr[index].center_freq, + ch.bw, ch.sb); + if (ch.bw == BRCMU_CHAN_BW_40) { /* assuming the order is HT20, HT40 Upper, * HT40 lower from chanspecs */ @@ -5213,6 +5215,46 @@ exit: return err; } +static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) +{ + u32 band, mimo_bwcap; + int err; + + band = WLC_BAND_2G; + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); + if (!err) { + bw_cap[IEEE80211_BAND_2GHZ] = band; + band = WLC_BAND_5G; + err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band); + if (!err) { + bw_cap[IEEE80211_BAND_5GHZ] = band; + return; + } + WARN_ON(1); + return; + } + brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n"); + mimo_bwcap = 0; + err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap); + if (err) + /* assume 20MHz if firmware does not give a clue */ + mimo_bwcap = WLC_N_BW_20ALL; + + switch (mimo_bwcap) { + case WLC_N_BW_40ALL: + bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT; + /* fall-thru */ + case WLC_N_BW_20IN2G_40IN5G: + bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT; + /* fall-thru */ + case WLC_N_BW_20ALL: + bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT; + bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT; + break; + default: + brcmf_err("invalid mimo_bw_cap value\n"); + } +} static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) { @@ -5221,13 +5263,13 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) s32 phy_list; u32 band_list[3]; u32 nmode; - u32 bw_cap = 0; + u32 bw_cap[2] = { 0, 0 }; s8 phy; s32 err; u32 nband; s32 i; - struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; - s32 index; + struct ieee80211_supported_band *bands[2] = { NULL, NULL }; + struct ieee80211_supported_band *band; err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, &phy_list, sizeof(phy_list)); @@ -5253,11 +5295,10 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) if (err) { brcmf_err("nmode error (%d)\n", err); } else { - err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap); - if (err) - brcmf_err("mimo_bw_cap error (%d)\n", err); + brcmf_get_bwcap(ifp, bw_cap); } - brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap); + brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, + bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); err = brcmf_construct_reginfo(cfg, bw_cap); if (err) { @@ -5266,40 +5307,33 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) } nband = band_list[0]; - memset(bands, 0, sizeof(bands)); for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) { - index = -1; + band = NULL; if ((band_list[i] == WLC_BAND_5G) && - (__wl_band_5ghz_a.n_channels > 0)) { - index = IEEE80211_BAND_5GHZ; - bands[index] = &__wl_band_5ghz_a; - if ((bw_cap == WLC_N_BW_40ALL) || - (bw_cap == WLC_N_BW_20IN2G_40IN5G)) - bands[index]->ht_cap.cap |= - IEEE80211_HT_CAP_SGI_40; - } else if ((band_list[i] == WLC_BAND_2G) && - (__wl_band_2ghz.n_channels > 0)) { - index = IEEE80211_BAND_2GHZ; - bands[index] = &__wl_band_2ghz; - if (bw_cap == WLC_N_BW_40ALL) - bands[index]->ht_cap.cap |= - IEEE80211_HT_CAP_SGI_40; - } + (__wl_band_5ghz_a.n_channels > 0)) + band = &__wl_band_5ghz_a; + else if ((band_list[i] == WLC_BAND_2G) && + (__wl_band_2ghz.n_channels > 0)) + band = &__wl_band_2ghz; + else + continue; - if ((index >= 0) && nmode) { - bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; - bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; - bands[index]->ht_cap.ht_supported = true; - bands[index]->ht_cap.ampdu_factor = - IEEE80211_HT_MAX_AMPDU_64K; - bands[index]->ht_cap.ampdu_density = - IEEE80211_HT_MPDU_DENSITY_16; - /* An HT shall support all EQM rates for one spatial - * stream - */ - bands[index]->ht_cap.mcs.rx_mask[0] = 0xff; + if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) { + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; + band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; } + band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; + band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40; + band->ht_cap.ht_supported = true; + band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; + band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16; + /* An HT shall support all EQM rates for one spatial + * stream + */ + band->ht_cap.mcs.rx_mask[0] = 0xff; + band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; + bands[band->band] = band; } wiphy = cfg_to_wiphy(cfg); -- cgit v1.1 From af35f55f94595c34076b7bf1cbe0087429d1ae5b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:42 +0100 Subject: brcmfmac: add sdio drive strength programming for bcm4334 chipset The table for BCM4334 SDIO drive strength programming was missing from the driver. Adding it with this patch set. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 5f39f28..6aa6ba0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -83,6 +83,13 @@ static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = { {0, 0x1} }; +/* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */ +static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = { + {3, 0x3}, + {2, 0x2}, + {1, 0x1}, + {0, 0x0} }; + /* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { {16, 0x7}, @@ -757,6 +764,11 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, str_mask = 0x00003800; str_shift = 11; break; + case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17): + str_tab = sdiod_drvstr_tab6_1v8; + str_mask = 0x00001800; + str_shift = 11; + break; case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17): /* note: 43143 does not support tristate */ i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1; -- cgit v1.1 From 3bd44d991f1906ee71807e07b388d9d2d94b7f7a Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:43 +0100 Subject: brcmfmac: correct detection of save&restore device capability The detection of the save&restore capability in brcmf_sdio_sr_capable() is only valid for certain chipsets. This patch should cover it for all chipsets currently supported. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 29 ++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 270cf9b..ae5f040 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3384,7 +3384,8 @@ err: static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus) { - u32 addr, reg; + u32 addr, reg, pmu_cc3_mask = ~0; + int err; brcmf_dbg(TRACE, "Enter\n"); @@ -3392,13 +3393,27 @@ static bool brcmf_sdio_sr_capable(struct brcmf_sdio *bus) if (bus->ci->pmurev < 17) return false; - /* read PMU chipcontrol register 3*/ - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); - brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL); - addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); - reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL); + switch (bus->ci->chip) { + case BCM43241_CHIP_ID: + case BCM4335_CHIP_ID: + case BCM4339_CHIP_ID: + /* read PMU chipcontrol register 3 */ + addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_addr); + brcmf_sdiod_regwl(bus->sdiodev, addr, 3, NULL); + addr = CORE_CC_REG(bus->ci->c_inf[0].base, chipcontrol_data); + reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL); + return (reg & pmu_cc3_mask) != 0; + default: + addr = CORE_CC_REG(bus->ci->c_inf[0].base, pmucapabilities_ext); + reg = brcmf_sdiod_regrl(bus->sdiodev, addr, &err); + if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0) + return false; - return (bool)reg; + addr = CORE_CC_REG(bus->ci->c_inf[0].base, retention_ctl); + reg = brcmf_sdiod_regrl(bus->sdiodev, addr, NULL); + return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK | + PMU_RCTL_LOGIC_DISABLE_MASK)) == 0; + } } static void brcmf_sdio_sr_init(struct brcmf_sdio *bus) -- cgit v1.1 From d6ae2c51becb5b901cbaf321e24a6362b14e4cdc Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:44 +0100 Subject: brcmfmac: enable watchdog when bus initialization is complete Change condition in brcmf_sdio_wd_timer() function to program watchdog only when in BRCMF_BUS_DATA state. This avoids watchdog being active during initialization. During initialization the SDIO save&restore capability is determined which affect the bus sleep mechanism used in watchdog thread. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index ae5f040..124f5e8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -4105,7 +4105,7 @@ void brcmf_sdio_wd_timer(struct brcmf_sdio *bus, uint wdtick) } /* don't start the wd until fw is loaded */ - if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) + if (bus->sdiodev->bus_if->state != BRCMF_BUS_DATA) return; if (wdtick) { -- cgit v1.1 From 76a4c6817c28dbc91fab8c366a177fa7215b2811 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:45 +0100 Subject: brcmfmac: only disable clock when brcmf_sdio_bus_init() fails The condition to disable the clock at the end of brcmf_sdio_bus_init() was wrong as the bus state is updated by the calling function. Hence, the clock was always disabled after brcmf_sdio_bus_init() which was not the intended behaviour. Reviewed-by: Hante Meuleman Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 124f5e8..2bf4757 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3630,7 +3630,7 @@ static int brcmf_sdio_bus_init(struct device *dev) } /* If we didn't come up, turn off backplane clock */ - if (bus_if->state != BRCMF_BUS_DATA) + if (ret != 0) brcmf_sdio_clkctl(bus, CLK_NONE, false); exit: -- cgit v1.1 From 43dffbc6be148030de1f4ee8d241f1384016c689 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:46 +0100 Subject: brcmfmac: inform cfg80211 when changing the CONNECTED state Upon unload of the brcmfmac driver it gave a kernel warning because cfg80211 still believed to be connected to an AP. The brcmfmac had already transitioned to disconnected state during unload. This patch adds informing cfg80211 about this transition. This will get rid of warning from cfg80211 seen upon module unload: ------------[ cut here ]------------ WARNING: CPU: 3 PID: 24303 at net/wireless/core.c:952 cfg80211_netdev_notifier_call+0x193/0x640 [cfg80211]() Modules linked in: brcmfmac(O-) brcmutil(O) cfg80211(O) ... [last unloaded: bcma] CPU: 3 PID: 24303 Comm: rmmod Tainted: G W O 3.13.0-rc4-wl-testing-x64-00002-gb472b6d-dirty #1 Hardware name: Dell Inc. Latitude E6410/07XJP9, BIOS A07 02/15/2011 00000000000003b8 ffff8800b211faf8 ffffffff815a7fcd 0000000000000007 0000000000000000 ffff8800b211fb38 ffffffff8104819c ffff880000000000 ffff8800c889d008 ffff8800b2000220 ffff8800c889a000 ffff8800c889d018 Call Trace: [] dump_stack+0x46/0x58 [] warn_slowpath_common+0x8c/0xc0 [] warn_slowpath_null+0x1a/0x20 [] cfg80211_netdev_notifier_call+0x193/0x640 [cfg80211] [] ? arp_ifdown+0x18/0x20 [] ? fib_disable_ip+0x3a/0x50 [] notifier_call_chain+0x4d/0x70 [] raw_notifier_call_chain+0x16/0x20 [] call_netdevice_notifiers_info+0x40/0x70 [] call_netdevice_notifiers+0x16/0x20 [] rollback_registered_many+0x17d/0x280 [] rollback_registered+0x2d/0x40 [] unregister_netdevice_queue+0x68/0xd0 [] unregister_netdev+0x20/0x30 [] brcmf_del_if+0xce/0x180 [brcmfmac] [] brcmf_detach+0x6c/0xe0 [brcmfmac] Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index a7c1afe..8cc9444 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -1095,10 +1095,10 @@ static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) BRCMF_C_DISASSOC, NULL, 0); if (err) { brcmf_err("WLC_DISASSOC failed (%d)\n", err); - cfg80211_disconnected(vif->wdev.netdev, 0, - NULL, 0, GFP_KERNEL); } clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); + cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL); + } clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); @@ -1758,6 +1758,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, return -EIO; clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state); + cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL); memcpy(&scbval.ea, &profile->bssid, ETH_ALEN); scbval.val = cpu_to_le32(reason_code); -- cgit v1.1 From 427dec5fc84d6d99f433a6eb008e97aea1757cfb Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:47 +0100 Subject: brcmfmac: move wiphy_unregister() call to brcmf_cfg80211_detach() The wiphy_unregister() call was done in brcmf_free_vif() when the last interface was being removed. This is not the obvious place to do that. This patch moves it to the brcmf_cfg80211_detach(). This removes the need to keep count of interfaces. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 26 +++++++++------------- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 26 +++++----------------- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 4 +--- 3 files changed, 18 insertions(+), 38 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index d318036..af5c4c7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -1956,21 +1956,21 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg) err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); if (err < 0) { brcmf_err("set p2p_disc error\n"); - brcmf_free_vif(cfg, p2p_vif); + brcmf_free_vif(p2p_vif); goto exit; } /* obtain bsscfg index for P2P discovery */ err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx); if (err < 0) { brcmf_err("retrieving discover bsscfg index failed\n"); - brcmf_free_vif(cfg, p2p_vif); + brcmf_free_vif(p2p_vif); goto exit; } /* Verify that firmware uses same bssidx as driver !! */ if (p2p_ifp->bssidx != bssidx) { brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n", bssidx, p2p_ifp->bssidx); - brcmf_free_vif(cfg, p2p_vif); + brcmf_free_vif(p2p_vif); goto exit; } @@ -1998,7 +1998,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p) brcmf_p2p_cancel_remain_on_channel(vif->ifp); brcmf_p2p_deinit_discovery(p2p); /* remove discovery interface */ - brcmf_free_vif(p2p->cfg, vif); + brcmf_free_vif(vif); p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; } /* just set it all to zero */ @@ -2223,7 +2223,7 @@ static struct wireless_dev *brcmf_p2p_create_p2pdev(struct brcmf_p2p_info *p2p, return &p2p_vif->wdev; fail: - brcmf_free_vif(p2p->cfg, p2p_vif); + brcmf_free_vif(p2p_vif); return ERR_PTR(err); } @@ -2232,12 +2232,12 @@ fail: * * @vif: virtual interface object to delete. */ -static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg, +static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p, struct brcmf_cfg80211_vif *vif) { cfg80211_unregister_wdev(&vif->wdev); - cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; - brcmf_free_vif(cfg, vif); + p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; + brcmf_free_vif(vif); } /** @@ -2247,15 +2247,13 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_cfg80211_info *cfg, */ static void brcmf_p2p_free_p2p_if(struct net_device *ndev) { - struct brcmf_cfg80211_info *cfg; struct brcmf_cfg80211_vif *vif; struct brcmf_if *ifp; ifp = netdev_priv(ndev); - cfg = ifp->drvr->config; vif = ifp->vif; - brcmf_free_vif(cfg, vif); + brcmf_free_vif(vif); free_netdev(ifp->ndev); } @@ -2350,7 +2348,7 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, return &ifp->vif->wdev; fail: - brcmf_free_vif(cfg, vif); + brcmf_free_vif(vif); return ERR_PTR(err); } @@ -2359,8 +2357,6 @@ fail: * * @wiphy: wiphy device of interface. * @wdev: wireless device of interface. - * - * TODO: not yet supported. */ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) { @@ -2386,7 +2382,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev) break; case NL80211_IFTYPE_P2P_DEVICE: - brcmf_p2p_delete_p2pdev(cfg, vif); + brcmf_p2p_delete_p2pdev(p2p, vif); return 0; default: return -ENOTSUPP; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 8cc9444..5598a20 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4360,9 +4360,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, { struct brcmf_cfg80211_vif *vif; - if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT) - return ERR_PTR(-ENOSPC); - brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n", sizeof(*vif)); vif = kzalloc(sizeof(*vif), GFP_KERNEL); @@ -4379,21 +4376,13 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, brcmf_init_prof(&vif->profile); list_add_tail(&vif->list, &cfg->vif_list); - cfg->vif_cnt++; return vif; } -void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, - struct brcmf_cfg80211_vif *vif) +void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) { list_del(&vif->list); - cfg->vif_cnt--; - kfree(vif); - if (!cfg->vif_cnt) { - wiphy_unregister(cfg->wiphy); - wiphy_free(cfg->wiphy); - } } static bool brcmf_is_linkup(const struct brcmf_event_msg *e) @@ -4980,20 +4969,17 @@ cfg80211_p2p_attach_out: wl_deinit_priv(cfg); cfg80211_attach_out: - brcmf_free_vif(cfg, vif); + brcmf_free_vif(vif); return NULL; } void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) { - struct brcmf_cfg80211_vif *vif; - struct brcmf_cfg80211_vif *tmp; - - wl_deinit_priv(cfg); + WARN_ON(!list_empty(&cfg->vif_list)); + wiphy_unregister(cfg->wiphy); brcmf_btcoex_detach(cfg); - list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) { - brcmf_free_vif(cfg, vif); - } + wl_deinit_priv(cfg); + wiphy_free(cfg->wiphy); } static s32 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index d9bdaf9..d9b2d62 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -412,7 +412,6 @@ struct brcmf_cfg80211_info { struct work_struct escan_timeout_work; u8 *escan_ioctl_buf; struct list_head vif_list; - u8 vif_cnt; struct brcmf_cfg80211_vif_event vif_event; struct completion vif_disabled; struct brcmu_d11inf d11inf; @@ -487,8 +486,7 @@ enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, enum nl80211_iftype type, bool pm_block); -void brcmf_free_vif(struct brcmf_cfg80211_info *cfg, - struct brcmf_cfg80211_vif *vif); +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); -- cgit v1.1 From e14799514da335159879bb8c37d5c4491357b0b4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:48 +0100 Subject: brcmfmac: call brcmf_cfg80211_detach() after removal of interfaces Instead of calling brcmf_cfg80211_detach() in brcmf_del_if() when deleting the primary interface, call it in brcmf_detach() after deleting all interfaces. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 7 +++---- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index bce0b8e..d3c4fba 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -859,8 +859,6 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx) } /* unregister will take care of freeing it */ unregister_netdev(ifp->ndev); - if (bssidx == 0) - brcmf_cfg80211_detach(drvr->config); } else { kfree(ifp); } @@ -963,8 +961,7 @@ int brcmf_bus_start(struct device *dev) fail: if (ret < 0) { brcmf_err("failed: %d\n", ret); - if (drvr->config) - brcmf_cfg80211_detach(drvr->config); + brcmf_cfg80211_detach(drvr->config); if (drvr->fws) { brcmf_fws_del_interface(ifp); brcmf_fws_deinit(drvr); @@ -1039,6 +1036,8 @@ void brcmf_detach(struct device *dev) brcmf_del_if(drvr, i); } + brcmf_cfg80211_detach(drvr->config); + brcmf_bus_detach(drvr); brcmf_proto_detach(drvr); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 5598a20..3e3de34 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4975,6 +4975,9 @@ cfg80211_attach_out: void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) { + if (!cfg) + return; + WARN_ON(!list_empty(&cfg->vif_list)); wiphy_unregister(cfg->wiphy); brcmf_btcoex_detach(cfg); -- cgit v1.1 From 9df4d542fc716fa2235d20afd086d78253901612 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:49 +0100 Subject: brcmfmac: use custom destructor callback for all netdevice interfaces The destructor for net devices was set to free_netdev() to get rid of it and the private data. The private data refers to a brcmf_if instance, but indirectly it also refers to brcmf_cfg80211_vif which holds the wdev. This is freed as well by using a new custom destructor called brcmf_cfg80211_free_netdev(). Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 19 ------------------- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 12 ++++++++++++ drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 1 + 4 files changed, 14 insertions(+), 20 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index d3c4fba..af39eda 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -702,7 +702,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked) brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); - ndev->destructor = free_netdev; + ndev->destructor = brcmf_cfg80211_free_netdev; return 0; fail: diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index af5c4c7..e23c869 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -2241,23 +2241,6 @@ static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p, } /** - * brcmf_p2p_free_p2p_if() - free up net device related data. - * - * @ndev: net device that needs to be freed. - */ -static void brcmf_p2p_free_p2p_if(struct net_device *ndev) -{ - struct brcmf_cfg80211_vif *vif; - struct brcmf_if *ifp; - - ifp = netdev_priv(ndev); - vif = ifp->vif; - - brcmf_free_vif(vif); - free_netdev(ifp->ndev); -} - -/** * brcmf_p2p_add_vif() - create a new P2P virtual interface. * * @wiphy: wiphy device of new interface. @@ -2334,8 +2317,6 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name, brcmf_err("Registering netdevice failed\n"); goto fail; } - /* override destructor */ - ifp->ndev->destructor = brcmf_p2p_free_p2p_if; cfg->p2p.bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = vif; /* Disable firmware roaming for P2P interface */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 3e3de34..aad83ae 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -4385,6 +4385,18 @@ void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) kfree(vif); } +void brcmf_cfg80211_free_netdev(struct net_device *ndev) +{ + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; + + ifp = netdev_priv(ndev); + vif = ifp->vif; + + brcmf_free_vif(vif); + free_netdev(ndev); +} + static bool brcmf_is_linkup(const struct brcmf_event_msg *e) { u32 event = e->event_code; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index d9b2d62..2dc6a07 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -505,5 +505,6 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, bool fw_abort); void brcmf_set_mpc(struct brcmf_if *ndev, int mpc); void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg); +void brcmf_cfg80211_free_netdev(struct net_device *ndev); #endif /* _wl_cfg80211_h_ */ -- cgit v1.1 From 6e08d757b72f280c45cfec61e63216adb419e2dd Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 6 Jan 2014 12:40:50 +0100 Subject: mmc: add SDIO identifiers for Broadcom WLAN devices The SDIO identifier for Broadcom WLAN devices were defined in the brcmfmac SDIO driver. Moving the definitions in MMC header file seems common sense. Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 -- drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | 1 + drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | 8 -------- 3 files changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 07015e1..68dd999 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -47,8 +47,6 @@ #define SDIOH_API_ACCESS_RETRY_LIMIT 2 -#define SDIO_VENDOR_ID_BROADCOM 0x02d0 - #define DMA_ALIGN_MASK 0x03 #define SDIO_FUNC1_BLOCKSIZE 64 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 6aa6ba0..a0b8409 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index d0f4b45..7ea424e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -54,14 +54,6 @@ #define BRCMF_MAX_CORENUM 6 -/* SDIO device ID */ -#define SDIO_DEVICE_ID_BROADCOM_43143 43143 -#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 -#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 -#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 -#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 -#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 - struct chip_core_info { u16 id; u16 rev; -- cgit v1.1 From 11e69c36eefd625db543a109789358be14d4cd5c Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 8 Jan 2014 10:49:33 +0100 Subject: brcmfmac: add support for bcm43362 device This patch adds support for the bcm43362 1x1 11n chipset. This chipset is used in AP6210 wifi module found on Cubieboard [1]. [1] http://cubieboard.org/ Reviewed-by: Franky Lin Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 5 ++++ .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 33 ++++++++++++++++++++++ 3 files changed, 39 insertions(+) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 68dd999..34c993d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -945,6 +945,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4335_4339)}, { /* end: all zeroes */ }, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 2bf4757..9c7f08a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -509,6 +509,8 @@ enum brcmf_sdio_frmtype { #define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" #define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" #define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" +#define BCM43362_FIRMWARE_NAME "brcm/brcmfmac43362-sdio.bin" +#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" #define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" #define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" @@ -526,6 +528,8 @@ MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); MODULE_FIRMWARE(BCM4334_NVRAM_NAME); MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); MODULE_FIRMWARE(BCM4335_NVRAM_NAME); +MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME); +MODULE_FIRMWARE(BCM43362_NVRAM_NAME); MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); MODULE_FIRMWARE(BCM4339_NVRAM_NAME); @@ -552,6 +556,7 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, + { BCM43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) } }; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index a0b8409..9fd4067 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -84,6 +84,17 @@ static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = { {0, 0x1} }; +/* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */ +static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = { + {6, 0x7}, + {5, 0x6}, + {4, 0x5}, + {3, 0x4}, + {2, 0x2}, + {1, 0x1}, + {0, 0x0} +}; + /* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */ static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = { {3, 0x3}, @@ -577,6 +588,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->ramsize = 0xc0000; ci->rambase = 0x180000; break; + case BCM43362_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x27004211; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18002000; + ci->c_inf[1].wrapbase = 0x18102000; + ci->c_inf[1].cib = 0x0a004211; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = 0x18004000; + ci->c_inf[2].wrapbase = 0x18104000; + ci->c_inf[2].cib = 0x08080401; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = 0x18003000; + ci->c_inf[3].wrapbase = 0x18103000; + ci->c_inf[3].cib = 0x03004211; + ci->ramsize = 0x3C000; + break; default: brcmf_err("chipid 0x%x is not supported\n", ci->chip); return -ENODEV; @@ -782,6 +810,11 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, brcmf_sdio_chip_name(ci->chip, chn, 8), drivestrength); break; + case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13): + str_tab = sdiod_drive_strength_tab5_1v8; + str_mask = 0x00003800; + str_shift = 11; + break; default: brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", brcmf_sdio_chip_name(ci->chip, chn, 8), -- cgit v1.1 From a74d036f98280b0de312f842ad09c26de56f27c5 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Mon, 13 Jan 2014 22:20:22 +0100 Subject: brcmfmac: Create common nvram parsing routines. New bus layers like pcie require nvram parsing routines which are the same routines as being used by sdio. Make these routines common in the new file nvram.c. Update sdio to use these routines and simplify the nvram upload process. Also add memory validation check for downloaded firmware and nvram in debug mode. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/Makefile | 1 + drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 166 ++++++++++----------- drivers/net/wireless/brcm80211/brcmfmac/nvram.c | 94 ++++++++++++ drivers/net/wireless/brcm80211/brcmfmac/nvram.h | 24 +++ .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 110 +------------- .../net/wireless/brcm80211/brcmfmac/sdio_chip.h | 3 +- 6 files changed, 208 insertions(+), 190 deletions(-) create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/nvram.c create mode 100644 drivers/net/wireless/brcm80211/brcmfmac/nvram.h (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 5681b98..57cddee 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -32,6 +32,7 @@ brcmfmac-objs += \ bcdc.o \ dhd_common.o \ dhd_linux.o \ + nvram.o \ btcoex.o brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ dhd_sdio.o \ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 9c7f08a..4f936c6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -41,6 +41,7 @@ #include #include "sdio_host.h" #include "sdio_chip.h" +#include "nvram.h" #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ @@ -369,8 +370,6 @@ struct brcmf_sdio_hdrinfo { struct brcmf_sdio { struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ struct chip_info *ci; /* Chip info struct */ - char *vars; /* Variables (from CIS and/or other) */ - uint varsz; /* Size of variables buffer */ u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ @@ -3207,8 +3206,7 @@ static bool brcmf_sdio_download_state(struct brcmf_sdio *bus, bool enter) brcmf_sdio_chip_enter_download(bus->sdiodev, ci); } else { - if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci, bus->vars, - bus->varsz)) + if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci)) return false; /* Allow HT Clock now that the ARM is running. */ @@ -3220,6 +3218,60 @@ static bool brcmf_sdio_download_state(struct brcmf_sdio *bus, bool enter) return true; } +#ifdef DEBUG +static bool +brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr, + u8 *ram_data, uint ram_sz) +{ + char *ram_cmp; + int err; + bool ret = true; + int address; + int offset; + int len; + + /* read back and verify */ + brcmf_dbg(INFO, "Compare RAM dl & ul at 0x%08x; size=%d\n", ram_addr, + ram_sz); + ram_cmp = kmalloc(MEMBLOCK, GFP_KERNEL); + /* do not proceed while no memory but */ + if (!ram_cmp) + return true; + + address = ram_addr; + offset = 0; + while (offset < ram_sz) { + len = ((offset + MEMBLOCK) < ram_sz) ? MEMBLOCK : + ram_sz - offset; + err = brcmf_sdiod_ramrw(sdiodev, false, address, ram_cmp, len); + if (err) { + brcmf_err("error %d on reading %d membytes at 0x%08x\n", + err, len, address); + ret = false; + break; + } else if (memcmp(ram_cmp, &ram_data[offset], len)) { + brcmf_err("Downloaded RAM image is corrupted, block offset is %d, len is %d\n", + offset, len); + ret = false; + break; + } + offset += len; + address += len; + } + + kfree(ram_cmp); + + return ret; +} +#else /* DEBUG */ +static bool +brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr, + u8 *ram_data, uint ram_sz) +{ + return true; +} +#endif /* DEBUG */ + static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) { const struct firmware *fw; @@ -3228,6 +3280,8 @@ static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) int address; int len; + brcmf_dbg(TRACE, "Enter\n"); + fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN); if (fw == NULL) return -ENOENT; @@ -3252,6 +3306,10 @@ static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) offset += len; address += len; } + if (!err) + if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase, + (u8 *)fw->data, fw->size)) + err = -EIO; failure: release_firmware(fw); @@ -3259,94 +3317,37 @@ failure: return err; } -/* - * ProcessVars:Takes a buffer of "=\n" lines read from a file - * and ending in a NUL. - * Removes carriage returns, empty lines, comment lines, and converts - * newlines to NULs. - * Shortens buffer as needed and pads with NULs. End of buffer is marked - * by two NULs. -*/ - -static int brcmf_sdio_strip_nvram(struct brcmf_sdio *bus, - const struct firmware *nv) -{ - char *varbuf; - char *dp; - bool findNewline; - int column; - int ret = 0; - uint buf_len, n, len; - - len = nv->size; - varbuf = vmalloc(len); - if (!varbuf) - return -ENOMEM; - - memcpy(varbuf, nv->data, len); - dp = varbuf; - - findNewline = false; - column = 0; - - for (n = 0; n < len; n++) { - if (varbuf[n] == 0) - break; - if (varbuf[n] == '\r') - continue; - if (findNewline && varbuf[n] != '\n') - continue; - findNewline = false; - if (varbuf[n] == '#') { - findNewline = true; - continue; - } - if (varbuf[n] == '\n') { - if (column == 0) - continue; - *dp++ = 0; - column = 0; - continue; - } - *dp++ = varbuf[n]; - column++; - } - buf_len = dp - varbuf; - while (dp < varbuf + n) - *dp++ = 0; - - kfree(bus->vars); - /* roundup needed for download to device */ - bus->varsz = roundup(buf_len + 1, 4); - bus->vars = kmalloc(bus->varsz, GFP_KERNEL); - if (bus->vars == NULL) { - bus->varsz = 0; - ret = -ENOMEM; - goto err; - } - - /* copy the processed variables and add null termination */ - memcpy(bus->vars, varbuf, buf_len); - bus->vars[buf_len] = 0; -err: - vfree(varbuf); - return ret; -} - static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus) { const struct firmware *nv; - int ret; + void *vars; + u32 varsz; + int address; + int err; + + brcmf_dbg(TRACE, "Enter\n"); nv = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM); if (nv == NULL) return -ENOENT; - ret = brcmf_sdio_strip_nvram(bus, nv); - + vars = brcmf_nvram_strip(nv, &varsz); release_firmware(nv); - return ret; + if (vars == NULL) + return -EINVAL; + + address = bus->ci->ramsize - varsz + bus->ci->rambase; + err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, vars, varsz); + if (err) + brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n", + err, varsz, address); + else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz)) + err = -EIO; + + brcmf_nvram_free(vars); + + return err; } static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus) @@ -4092,7 +4093,6 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) brcmu_pkt_buf_free_skb(bus->txglom_sgpad); kfree(bus->rxbuf); kfree(bus->hdrbuf); - kfree(bus->vars); kfree(bus); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.c b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c new file mode 100644 index 0000000..d5ef86d --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "nvram.h" + +/* brcmf_nvram_strip :Takes a buffer of "=\n" lines read from a file + * and ending in a NUL. Removes carriage returns, empty lines, comment lines, + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. + * End of buffer is completed with token identifying length of buffer. + */ +void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length) +{ + u8 *nvram; + u32 i; + u32 len; + u32 column; + u8 val; + bool comment; + u32 token; + __le32 token_le; + + /* Alloc for extra 0 byte + roundup by 4 + length field */ + nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL); + if (!nvram) + return NULL; + + len = 0; + column = 0; + comment = false; + for (i = 0; i < nv->size; i++) { + val = nv->data[i]; + if (val == 0) + break; + if (val == '\r') + continue; + if (comment && (val != '\n')) + continue; + comment = false; + if (val == '#') { + comment = true; + continue; + } + if (val == '\n') { + if (column == 0) + continue; + nvram[len] = 0; + len++; + column = 0; + continue; + } + nvram[len] = val; + len++; + column++; + } + column = len; + *new_length = roundup(len + 1, 4); + while (column != *new_length) { + nvram[column] = 0; + column++; + } + + token = *new_length / 4; + token = (~token << 16) | (token & 0x0000FFFF); + token_le = cpu_to_le32(token); + + memcpy(&nvram[*new_length], &token_le, sizeof(token_le)); + *new_length += sizeof(token_le); + + return nvram; +} + +void brcmf_nvram_free(void *nvram) +{ + kfree(nvram); +} + + diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.h b/drivers/net/wireless/brcm80211/brcmfmac/nvram.h new file mode 100644 index 0000000..d4545809 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2013 Broadcom Corporation + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef BRCMFMAC_NVRAM_H +#define BRCMFMAC_NVRAM_H + + +void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length); +void brcmf_nvram_free(void *nvram); + + +#endif /* BRCMFMAC_NVRAM_H */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 9fd4067..a74a3d1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -842,107 +842,16 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, } } -#ifdef DEBUG -static bool -brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr, - char *nvram_dat, uint nvram_sz) -{ - char *nvram_ularray; - int err; - bool ret = true; - - /* read back and verify */ - brcmf_dbg(INFO, "Compare NVRAM dl & ul; size=%d\n", nvram_sz); - nvram_ularray = kmalloc(nvram_sz, GFP_KERNEL); - /* do not proceed while no memory but */ - if (!nvram_ularray) - return true; - - /* Upload image to verify downloaded contents. */ - memset(nvram_ularray, 0xaa, nvram_sz); - - /* Read the vars list to temp buffer for comparison */ - err = brcmf_sdiod_ramrw(sdiodev, false, nvram_addr, nvram_ularray, - nvram_sz); - if (err) { - brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", - err, nvram_sz, nvram_addr); - } else if (memcmp(nvram_dat, nvram_ularray, nvram_sz)) { - brcmf_err("Downloaded NVRAM image is corrupted\n"); - ret = false; - } - kfree(nvram_ularray); - - return ret; -} -#else /* DEBUG */ -static inline bool -brcmf_sdio_chip_verifynvram(struct brcmf_sdio_dev *sdiodev, u32 nvram_addr, - char *nvram_dat, uint nvram_sz) -{ - return true; -} -#endif /* DEBUG */ - -static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, - char *nvram_dat, uint nvram_sz) -{ - int err; - u32 nvram_addr; - u32 token; - __le32 token_le; - - nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase; - - /* Write the vars list */ - err = brcmf_sdiod_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz); - if (err) { - brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n", - err, nvram_sz, nvram_addr); - return false; - } - - if (!brcmf_sdio_chip_verifynvram(sdiodev, nvram_addr, - nvram_dat, nvram_sz)) - return false; - - /* generate token: - * nvram size, converted to words, in lower 16-bits, checksum - * in upper 16-bits. - */ - token = nvram_sz / 4; - token = (~token << 16) | (token & 0x0000FFFF); - token_le = cpu_to_le32(token); - - brcmf_dbg(INFO, "RAM size: %d\n", ci->ramsize); - brcmf_dbg(INFO, "nvram is placed at %d, size %d, token=0x%08x\n", - nvram_addr, nvram_sz, token); - - /* Write the length token to the last word */ - if (brcmf_sdiod_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase), - (u8 *)&token_le, 4)) - return false; - - return true; -} - static void brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) { - u32 zeros = 0; - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); - - /* clear length token */ - brcmf_sdiod_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4); } static bool -brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, - char *nvram_dat, uint nvram_sz) +brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) { u8 core_idx; u32 reg_addr; @@ -952,9 +861,6 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, return false; } - if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz)) - return false; - /* clear all interrupts */ core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); reg_addr = ci->c_inf[core_idx].base; @@ -975,15 +881,11 @@ brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, } static bool -brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, - char *nvram_dat, uint nvram_sz) +brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) { u8 core_idx; u32 reg_addr; - if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz)) - return false; - /* clear all interrupts */ core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); reg_addr = ci->c_inf[core_idx].base; @@ -1015,15 +917,13 @@ void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, } bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, char *nvram_dat, - uint nvram_sz) + struct chip_info *ci) { u8 arm_core_idx; arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); if (BRCMF_MAX_CORENUM != arm_core_idx) - return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat, - nvram_sz); + return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci); - return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, nvram_dat, nvram_sz); + return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index 7ea424e..c7d0dbc 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -224,7 +224,6 @@ u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci); bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, char *nvram_dat, - uint nvram_sz); + struct chip_info *ci); #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ -- cgit v1.1 From 53036261033abdab7323a4a896a9bde84d2c2f17 Mon Sep 17 00:00:00 2001 From: Hante Meuleman Date: Mon, 13 Jan 2014 22:20:23 +0100 Subject: brcmfmac: update core reset and disable routines. The original core reset and disable routines do not work always on running system. These routines were updated to properly reset a core. When module is unloaded the device is put into download state where all necessary cores have been reset. This will make sure the device is in idle mode after module unload. Reviewed-by: Arend Van Spriel Reviewed-by: Franky (Zhenhui) Lin Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Hante Meuleman Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 8 +- .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 149 +++++++++++++-------- .../net/wireless/brcm80211/brcmfmac/sdio_chip.h | 6 +- 3 files changed, 106 insertions(+), 57 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4f936c6..1905789 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2263,8 +2263,6 @@ static void brcmf_sdio_bus_stop(struct device *dev) w_sdreg32(bus, local_hostintmask, offsetof(struct sdpcmd_regs, intstatus)); - /* Turn off the backplane clock (only) */ - brcmf_sdio_clkctl(bus, CLK_SDONLY, false); sdio_release_host(bus->sdiodev->func[1]); /* Clear the data packet queues */ @@ -4085,6 +4083,12 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) if (bus->ci) { sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + /* Leave the device in state where it is 'quiet'. This + * is done by putting it in download_state which + * essentially resets all necessary cores + */ + msleep(20); + brcmf_sdio_download_state(bus, true); brcmf_sdio_clkctl(bus, CLK_NONE, false); sdio_release_host(bus->sdiodev->func[1]); brcmf_sdio_chip_detach(&bus->ci); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index a74a3d1..43429764 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -51,6 +51,9 @@ #define BCM43143_CORE_ARM_BASE 0x18003000 #define BCM43143_RAMSIZE 0x70000 +/* All D11 cores, ID 0x812 */ +#define BCM43xx_CORE_D11_BASE 0x18001000 + #define SBCOREREV(sbidh) \ ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ ((sbidh) & SSB_IDHIGH_RCLO)) @@ -66,6 +69,10 @@ /* ARM CR4 core specific control flag bits */ #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 +/* D11 core specific control flag bits */ +#define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004 +#define D11_BCMA_IOCTL_PHYRESET 0x0008 + #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) /* SDIO Pad drive strength to select value mappings */ struct sdiod_drive_str { @@ -193,7 +200,8 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 core_bits) + struct chip_info *ci, u16 coreid, u32 pre_resetbits, + u32 in_resetbits) { u32 regdata, base; u8 idx; @@ -279,52 +287,48 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 core_bits) + struct chip_info *ci, u16 coreid, u32 pre_resetbits, + u32 in_resetbits) { u8 idx; u32 regdata; + u32 wrapbase; idx = brcmf_sdio_chip_getinfidx(ci, coreid); if (idx == BRCMF_MAX_CORENUM) return; + wrapbase = ci->c_inf[idx].wrapbase; + /* if core is already in reset, just return */ - regdata = brcmf_sdiod_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - NULL); + regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL); if ((regdata & BCMA_RESET_CTL_RESET) != 0) return; - /* ensure no pending backplane operation - * 300uc should be sufficient for backplane ops to be finish - * extra 10ms is taken into account for firmware load stage - * after 10300us carry on disabling the core anyway - */ - SPINWAIT(brcmf_sdiod_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_ST, - NULL), 10300); - regdata = brcmf_sdiod_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_ST, - NULL); - if (regdata) - brcmf_err("disabling core 0x%x with reset status %x\n", - coreid, regdata); + /* configure reset */ + brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits | + BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); - brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, + /* put in reset */ + brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, BCMA_RESET_CTL_RESET, NULL); - udelay(1); - - brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - core_bits, NULL); - regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); usleep_range(10, 20); + /* wait till reset is 1 */ + SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) != + BCMA_RESET_CTL_RESET, 300); + + /* post reset configure */ + brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits | + BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); } static void brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 core_bits) + struct chip_info *ci, u16 coreid, u32 pre_resetbits, + u32 in_resetbits, u32 post_resetbits) { u32 regdata; u8 idx; @@ -337,7 +341,8 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, * Must do the disable sequence first to work for * arbitrary current core state. */ - brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); + brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits, + in_resetbits); /* * Now do the initialization sequence. @@ -390,35 +395,32 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 core_bits) + struct chip_info *ci, u16 coreid, u32 pre_resetbits, + u32 in_resetbits, u32 post_resetbits) { u8 idx; u32 regdata; + u32 wrapbase; idx = brcmf_sdio_chip_getinfidx(ci, coreid); if (idx == BRCMF_MAX_CORENUM) return; + wrapbase = ci->c_inf[idx].wrapbase; + /* must disable first to work for arbitrary current core state */ - brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); + brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits, + in_resetbits); - /* now do initialization sequence */ - brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); - regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); - brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - 0, NULL); - regdata = brcmf_sdiod_regrl(sdiodev, - ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, - NULL); - udelay(1); + while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) & + BCMA_RESET_CTL_RESET) { + brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL); + usleep_range(40, 60); + } - brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - core_bits | BCMA_IOCTL_CLK, NULL); - regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, - NULL); - udelay(1); + brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits | + BCMA_IOCTL_CLK, NULL); + regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); } #ifdef DEBUG @@ -498,6 +500,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; ci->c_inf[3].cib = 0x07000000; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; ci->ramsize = BCM43143_RAMSIZE; break; case BCM43241_CHIP_ID: @@ -515,6 +520,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].base = 0x18003000; ci->c_inf[3].wrapbase = 0x18103000; ci->c_inf[3].cib = 0x07004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; ci->ramsize = 0x90000; break; case BCM4329_CHIP_ID: @@ -524,6 +532,8 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; ci->c_inf[3].id = BCMA_CORE_ARM_CM3; ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; ci->ramsize = BCM4329_RAMSIZE; break; case BCM4330_CHIP_ID: @@ -541,6 +551,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].base = 0x18003000; ci->c_inf[3].wrapbase = 0x18103000; ci->c_inf[3].cib = 0x03004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; ci->ramsize = 0x48000; break; case BCM4334_CHIP_ID: @@ -558,6 +571,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].base = 0x18003000; ci->c_inf[3].wrapbase = 0x18103000; ci->c_inf[3].cib = 0x07004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; ci->ramsize = 0x80000; break; case BCM4335_CHIP_ID: @@ -571,6 +587,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[2].base = 0x18002000; ci->c_inf[2].wrapbase = 0x18102000; ci->c_inf[2].cib = 0x01084411; + ci->c_inf[3].id = BCMA_CORE_80211; + ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; ci->ramsize = 0xc0000; ci->rambase = 0x180000; break; @@ -585,6 +604,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[2].base = 0x18002000; ci->c_inf[2].wrapbase = 0x18102000; ci->c_inf[2].cib = 0x04084411; + ci->c_inf[3].id = BCMA_CORE_80211; + ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; ci->ramsize = 0xc0000; ci->rambase = 0x180000; break; @@ -603,6 +625,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].base = 0x18003000; ci->c_inf[3].wrapbase = 0x18103000; ci->c_inf[3].cib = 0x03004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; ci->ramsize = 0x3C000; break; default: @@ -713,7 +738,7 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, * Make sure any on-chip ARM is off (in case strapping is wrong), * or downloaded code was already running. */ - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); + ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0); } int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, @@ -846,8 +871,11 @@ static void brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) { - ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); - ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); + ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0); + ci->resetcore(sdiodev, ci, BCMA_CORE_80211, + D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN, + D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN); + ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0); } static bool @@ -867,7 +895,7 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) reg_addr += offsetof(struct sdpcmd_regs, intstatus); brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); + ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0); return true; } @@ -876,8 +904,22 @@ static inline void brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) { - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, - ARMCR4_BCMA_IOCTL_CPUHALT); + u8 idx; + u32 regdata; + u32 wrapbase; + idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4); + + if (idx == BRCMF_MAX_CORENUM) + return; + + wrapbase = ci->c_inf[idx].wrapbase; + regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); + regdata &= ARMCR4_BCMA_IOCTL_CPUHALT; + ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata, + ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT); + ci->resetcore(sdiodev, ci, BCMA_CORE_80211, + D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN, + D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN); } static bool @@ -897,7 +939,8 @@ brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) sizeof(ci->rst_vec)); /* restore ARM */ - ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); + ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT, + 0, 0); return true; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index c7d0dbc..91c61cb 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -81,9 +81,11 @@ struct chip_info { u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u16 coreid); void (*coredisable)(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 core_bits); + struct chip_info *ci, u16 coreid, u32 pre_resetbits, + u32 in_resetbits); void (*resetcore)(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 core_bits); + struct chip_info *ci, u16 coreid, u32 pre_resetbits, + u32 in_resetbits, u32 post_resetbits); }; struct sbconfig { -- cgit v1.1 From 3355650c61c4e3d56deadb601762b09ed8a30939 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 13 Jan 2014 22:20:25 +0100 Subject: brcmfmac: rework firmware download code The firmware download code has been restructured so the reset vector does not need to be stored in a structure, but keep it on the stack to be passed to exit download function. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 87 ++++++++-------------- .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 11 +-- .../net/wireless/brcm80211/brcmfmac/sdio_chip.h | 2 +- 3 files changed, 40 insertions(+), 60 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 1905789..b9d5f73 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -3192,30 +3192,6 @@ brcmf_sdio_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) return rxlen ? (int)rxlen : -ETIMEDOUT; } -static bool brcmf_sdio_download_state(struct brcmf_sdio *bus, bool enter) -{ - struct chip_info *ci = bus->ci; - - /* To enter download state, disable ARM and reset SOCRAM. - * To exit download state, simply reset ARM (default is RAM boot). - */ - if (enter) { - bus->alp_only = true; - - brcmf_sdio_chip_enter_download(bus->sdiodev, ci); - } else { - if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci)) - return false; - - /* Allow HT Clock now that the ARM is running. */ - bus->alp_only = false; - - bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; - } - - return true; -} - #ifdef DEBUG static bool brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr, @@ -3270,9 +3246,9 @@ brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr, } #endif /* DEBUG */ -static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) +static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus, + const struct firmware *fw) { - const struct firmware *fw; int err; int offset; int address; @@ -3280,14 +3256,6 @@ static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); - fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN); - if (fw == NULL) - return -ENOENT; - - if (brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4) != - BRCMF_MAX_CORENUM) - memcpy(&bus->ci->rst_vec, fw->data, sizeof(bus->ci->rst_vec)); - err = 0; offset = 0; address = bus->ci->rambase; @@ -3299,7 +3267,7 @@ static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) if (err) { brcmf_err("error %d on writing %d membytes at 0x%08x\n", err, len, address); - goto failure; + return err; } offset += len; address += len; @@ -3309,15 +3277,12 @@ static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus) (u8 *)fw->data, fw->size)) err = -EIO; -failure: - release_firmware(fw); - return err; } -static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus) +static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus, + const struct firmware *nv) { - const struct firmware *nv; void *vars; u32 varsz; int address; @@ -3325,12 +3290,7 @@ static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); - nv = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM); - if (nv == NULL) - return -ENOENT; - vars = brcmf_nvram_strip(nv, &varsz); - release_firmware(nv); if (vars == NULL) return -EINVAL; @@ -3351,33 +3311,52 @@ static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus) static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus) { int bcmerror = -EFAULT; - + const struct firmware *fw; + u32 rstvec; sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdio_clkctl(bus, CLK_AVAIL, false); /* Keep arm in reset */ - if (!brcmf_sdio_download_state(bus, true)) { - brcmf_err("error placing ARM core in reset\n"); + brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci); + + fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN); + if (fw == NULL) { + bcmerror = -ENOENT; goto err; } - if (brcmf_sdio_download_code_file(bus)) { + rstvec = get_unaligned_le32(fw->data); + brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec); + + bcmerror = brcmf_sdio_download_code_file(bus, fw); + release_firmware(fw); + if (bcmerror) { brcmf_err("dongle image file download failed\n"); goto err; } - if (brcmf_sdio_download_nvram(bus)) { + fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM); + if (fw == NULL) { + bcmerror = -ENOENT; + goto err; + } + + bcmerror = brcmf_sdio_download_nvram(bus, fw); + release_firmware(fw); + if (bcmerror) { brcmf_err("dongle nvram file download failed\n"); goto err; } /* Take arm out of reset */ - if (!brcmf_sdio_download_state(bus, false)) { + if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) { brcmf_err("error getting out of ARM core reset\n"); goto err; } + /* Allow HT Clock now that the ARM is running. */ + bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; bcmerror = 0; err: @@ -3566,9 +3545,11 @@ static int brcmf_sdio_bus_init(struct device *dev) /* try to download image and nvram to the dongle */ if (bus_if->state == BRCMF_BUS_DOWN) { + bus->alp_only = true; err = brcmf_sdio_download_firmware(bus); if (err) return err; + bus->alp_only = false; } if (!bus->sdiodev->bus_if->drvr) @@ -3778,8 +3759,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) u32 reg_val; u32 drivestrength; - bus->alp_only = true; - sdio_claim_host(bus->sdiodev->func[1]); pr_debug("F1 signature read @0x18000000=0x%4x\n", @@ -4088,7 +4067,7 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) * essentially resets all necessary cores */ msleep(20); - brcmf_sdio_download_state(bus, true); + brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci); brcmf_sdio_clkctl(bus, CLK_NONE, false); sdio_release_host(bus->sdiodev->func[1]); brcmf_sdio_chip_detach(&bus->ci); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 43429764..88eacf1 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -923,7 +923,8 @@ brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, } static bool -brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) +brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, + u32 rstvec) { u8 core_idx; u32 reg_addr; @@ -935,8 +936,8 @@ brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); /* Write reset vector to address 0 */ - brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, - sizeof(ci->rst_vec)); + brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&rstvec, + sizeof(rstvec)); /* restore ARM */ ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT, @@ -960,7 +961,7 @@ void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, } bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci) + struct chip_info *ci, u32 rstvec) { u8 arm_core_idx; @@ -968,5 +969,5 @@ bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, if (BRCMF_MAX_CORENUM != arm_core_idx) return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci); - return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci); + return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, rstvec); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index 91c61cb..9a72b71 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -226,6 +226,6 @@ u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci); bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci); + struct chip_info *ci, u32 rstvec); #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ -- cgit v1.1 From c805eeb7a8e165e218042a747ab41c2dbdc74885 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 13 Jan 2014 22:20:26 +0100 Subject: brcmfmac: restructure brcmf_sdio_chip_recognition() Rework function to allow only bcm4329 in case of chip backplane type being sonics sillicon backplane. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 333 +++++++++++---------- .../net/wireless/brcm80211/brcmfmac/sdio_chip.h | 1 - 2 files changed, 167 insertions(+), 167 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 88eacf1..d1de037 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -462,70 +462,38 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) { u32 regdata; - int ret; + u32 socitype; /* Get CC core rev - * Chipid is assume to be at offset 0 from regs arg + * Chipid is assume to be at offset 0 from SI_ENUM_BASE * For different chiptypes or old sdio hosts w/o chipcommon, * other ways of recognition should be added here. */ - ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; - ci->c_inf[0].base = SI_ENUM_BASE; regdata = brcmf_sdiod_regrl(sdiodev, - CORE_CC_REG(ci->c_inf[0].base, chipid), + CORE_CC_REG(SI_ENUM_BASE, chipid), NULL); ci->chip = regdata & CID_ID_MASK; ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && ci->chiprev >= 2) ci->chip = BCM4339_CHIP_ID; - ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; + socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; - brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); + brcmf_dbg(INFO, "found %s chip: id=0x%x, rev=%d\n", + socitype == SOCI_SB ? "SB" : "AXI", ci->chip, ci->chiprev); - /* Address of cores for new chips should be added here */ - switch (ci->chip) { - case BCM43143_CHIP_ID: - ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000; - ci->c_inf[0].cib = 0x2b000000; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = BCM43143_CORE_BUS_BASE; - ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000; - ci->c_inf[1].cib = 0x18000000; - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; - ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE; - ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000; - ci->c_inf[2].cib = 0x14000000; - ci->c_inf[3].id = BCMA_CORE_ARM_CM3; - ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; - ci->c_inf[3].cib = 0x07000000; - ci->c_inf[4].id = BCMA_CORE_80211; - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; - ci->ramsize = BCM43143_RAMSIZE; - break; - case BCM43241_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x2a084411; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18002000; - ci->c_inf[1].wrapbase = 0x18102000; - ci->c_inf[1].cib = 0x0e004211; - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; - ci->c_inf[2].base = 0x18004000; - ci->c_inf[2].wrapbase = 0x18104000; - ci->c_inf[2].cib = 0x14080401; - ci->c_inf[3].id = BCMA_CORE_ARM_CM3; - ci->c_inf[3].base = 0x18003000; - ci->c_inf[3].wrapbase = 0x18103000; - ci->c_inf[3].cib = 0x07004211; - ci->c_inf[4].id = BCMA_CORE_80211; - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; - ci->ramsize = 0x90000; - break; - case BCM4329_CHIP_ID: + if (socitype == SOCI_SB) { + if (ci->chip != BCM4329_CHIP_ID) { + brcmf_err("SB chip is not supported\n"); + return -ENODEV; + } + ci->iscoreup = brcmf_sdio_sb_iscoreup; + ci->corerev = brcmf_sdio_sb_corerev; + ci->coredisable = brcmf_sdio_sb_coredisable; + ci->resetcore = brcmf_sdio_sb_resetcore; + + ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; + ci->c_inf[0].base = SI_ENUM_BASE; ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; ci->c_inf[1].base = BCM4329_CORE_BUS_BASE; ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; @@ -535,129 +503,162 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[4].id = BCMA_CORE_80211; ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; ci->ramsize = BCM4329_RAMSIZE; - break; - case BCM4330_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x27004211; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18002000; - ci->c_inf[1].wrapbase = 0x18102000; - ci->c_inf[1].cib = 0x07004211; - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; - ci->c_inf[2].base = 0x18004000; - ci->c_inf[2].wrapbase = 0x18104000; - ci->c_inf[2].cib = 0x0d080401; - ci->c_inf[3].id = BCMA_CORE_ARM_CM3; - ci->c_inf[3].base = 0x18003000; - ci->c_inf[3].wrapbase = 0x18103000; - ci->c_inf[3].cib = 0x03004211; - ci->c_inf[4].id = BCMA_CORE_80211; - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; - ci->ramsize = 0x48000; - break; - case BCM4334_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x29004211; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18002000; - ci->c_inf[1].wrapbase = 0x18102000; - ci->c_inf[1].cib = 0x0d004211; - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; - ci->c_inf[2].base = 0x18004000; - ci->c_inf[2].wrapbase = 0x18104000; - ci->c_inf[2].cib = 0x13080401; - ci->c_inf[3].id = BCMA_CORE_ARM_CM3; - ci->c_inf[3].base = 0x18003000; - ci->c_inf[3].wrapbase = 0x18103000; - ci->c_inf[3].cib = 0x07004211; - ci->c_inf[4].id = BCMA_CORE_80211; - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; - ci->ramsize = 0x80000; - break; - case BCM4335_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x2b084411; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18005000; - ci->c_inf[1].wrapbase = 0x18105000; - ci->c_inf[1].cib = 0x0f004211; - ci->c_inf[2].id = BCMA_CORE_ARM_CR4; - ci->c_inf[2].base = 0x18002000; - ci->c_inf[2].wrapbase = 0x18102000; - ci->c_inf[2].cib = 0x01084411; - ci->c_inf[3].id = BCMA_CORE_80211; - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; - ci->ramsize = 0xc0000; - ci->rambase = 0x180000; - break; - case BCM4339_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x2e084411; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18005000; - ci->c_inf[1].wrapbase = 0x18105000; - ci->c_inf[1].cib = 0x15004211; - ci->c_inf[2].id = BCMA_CORE_ARM_CR4; - ci->c_inf[2].base = 0x18002000; - ci->c_inf[2].wrapbase = 0x18102000; - ci->c_inf[2].cib = 0x04084411; - ci->c_inf[3].id = BCMA_CORE_80211; - ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; - ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; - ci->ramsize = 0xc0000; - ci->rambase = 0x180000; - break; - case BCM43362_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x27004211; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18002000; - ci->c_inf[1].wrapbase = 0x18102000; - ci->c_inf[1].cib = 0x0a004211; - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; - ci->c_inf[2].base = 0x18004000; - ci->c_inf[2].wrapbase = 0x18104000; - ci->c_inf[2].cib = 0x08080401; - ci->c_inf[3].id = BCMA_CORE_ARM_CM3; - ci->c_inf[3].base = 0x18003000; - ci->c_inf[3].wrapbase = 0x18103000; - ci->c_inf[3].cib = 0x03004211; - ci->c_inf[4].id = BCMA_CORE_80211; - ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; - ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; - ci->ramsize = 0x3C000; - break; - default: - brcmf_err("chipid 0x%x is not supported\n", ci->chip); - return -ENODEV; - } - - ret = brcmf_sdio_chip_cichk(ci); - if (ret) - return ret; - - switch (ci->socitype) { - case SOCI_SB: - ci->iscoreup = brcmf_sdio_sb_iscoreup; - ci->corerev = brcmf_sdio_sb_corerev; - ci->coredisable = brcmf_sdio_sb_coredisable; - ci->resetcore = brcmf_sdio_sb_resetcore; - break; - case SOCI_AI: + } else if (socitype == SOCI_AI) { ci->iscoreup = brcmf_sdio_ai_iscoreup; ci->corerev = brcmf_sdio_ai_corerev; ci->coredisable = brcmf_sdio_ai_coredisable; ci->resetcore = brcmf_sdio_ai_resetcore; - break; - default: - brcmf_err("socitype %u not supported\n", ci->socitype); + + ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON; + ci->c_inf[0].base = SI_ENUM_BASE; + + /* Address of cores for new chips should be added here */ + switch (ci->chip) { + case BCM43143_CHIP_ID: + ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000; + ci->c_inf[0].cib = 0x2b000000; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = BCM43143_CORE_BUS_BASE; + ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000; + ci->c_inf[1].cib = 0x18000000; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE; + ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000; + ci->c_inf[2].cib = 0x14000000; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; + ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; + ci->c_inf[3].cib = 0x07000000; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; + ci->ramsize = BCM43143_RAMSIZE; + break; + case BCM43241_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x2a084411; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18002000; + ci->c_inf[1].wrapbase = 0x18102000; + ci->c_inf[1].cib = 0x0e004211; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = 0x18004000; + ci->c_inf[2].wrapbase = 0x18104000; + ci->c_inf[2].cib = 0x14080401; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = 0x18003000; + ci->c_inf[3].wrapbase = 0x18103000; + ci->c_inf[3].cib = 0x07004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; + ci->ramsize = 0x90000; + break; + case BCM4330_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x27004211; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18002000; + ci->c_inf[1].wrapbase = 0x18102000; + ci->c_inf[1].cib = 0x07004211; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = 0x18004000; + ci->c_inf[2].wrapbase = 0x18104000; + ci->c_inf[2].cib = 0x0d080401; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = 0x18003000; + ci->c_inf[3].wrapbase = 0x18103000; + ci->c_inf[3].cib = 0x03004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; + ci->ramsize = 0x48000; + break; + case BCM4334_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x29004211; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18002000; + ci->c_inf[1].wrapbase = 0x18102000; + ci->c_inf[1].cib = 0x0d004211; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = 0x18004000; + ci->c_inf[2].wrapbase = 0x18104000; + ci->c_inf[2].cib = 0x13080401; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = 0x18003000; + ci->c_inf[3].wrapbase = 0x18103000; + ci->c_inf[3].cib = 0x07004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; + ci->ramsize = 0x80000; + break; + case BCM4335_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x2b084411; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18005000; + ci->c_inf[1].wrapbase = 0x18105000; + ci->c_inf[1].cib = 0x0f004211; + ci->c_inf[2].id = BCMA_CORE_ARM_CR4; + ci->c_inf[2].base = 0x18002000; + ci->c_inf[2].wrapbase = 0x18102000; + ci->c_inf[2].cib = 0x01084411; + ci->c_inf[3].id = BCMA_CORE_80211; + ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; + ci->ramsize = 0xc0000; + ci->rambase = 0x180000; + break; + case BCM43362_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x27004211; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18002000; + ci->c_inf[1].wrapbase = 0x18102000; + ci->c_inf[1].cib = 0x0a004211; + ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; + ci->c_inf[2].base = 0x18004000; + ci->c_inf[2].wrapbase = 0x18104000; + ci->c_inf[2].cib = 0x08080401; + ci->c_inf[3].id = BCMA_CORE_ARM_CM3; + ci->c_inf[3].base = 0x18003000; + ci->c_inf[3].wrapbase = 0x18103000; + ci->c_inf[3].cib = 0x03004211; + ci->c_inf[4].id = BCMA_CORE_80211; + ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; + ci->ramsize = 0x3C000; + break; + case BCM4339_CHIP_ID: + ci->c_inf[0].wrapbase = 0x18100000; + ci->c_inf[0].cib = 0x2e084411; + ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; + ci->c_inf[1].base = 0x18005000; + ci->c_inf[1].wrapbase = 0x18105000; + ci->c_inf[1].cib = 0x15004211; + ci->c_inf[2].id = BCMA_CORE_ARM_CR4; + ci->c_inf[2].base = 0x18002000; + ci->c_inf[2].wrapbase = 0x18102000; + ci->c_inf[2].cib = 0x04084411; + ci->c_inf[3].id = BCMA_CORE_80211; + ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; + ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; + ci->ramsize = 0xc0000; + ci->rambase = 0x180000; + break; + default: + brcmf_err("AXI chip is not supported\n"); + return -ENODEV; + } + } else { + brcmf_err("chip backplane type %u is not supported\n", + socitype); return -ENODEV; } - return 0; + return brcmf_sdio_chip_cichk(ci); } static int diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index 9a72b71..a1aadf4 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -66,7 +66,6 @@ struct chip_core_info { struct chip_info { u32 chip; u32 chiprev; - u32 socitype; /* core info */ /* always put chipcommon core at 0, bus core at 1 */ struct chip_core_info c_inf[BRCMF_MAX_CORENUM]; -- cgit v1.1 From 9cf218fc333406764275eab9b0e47f5c39929e79 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 13 Jan 2014 22:20:27 +0100 Subject: brcmfmac: rename chip and core related structures Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 +- .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 54 +++++++++++----------- .../net/wireless/brcm80211/brcmfmac/sdio_chip.h | 27 +++++------ 3 files changed, 41 insertions(+), 42 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index b9d5f73..ef24a1b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -369,7 +369,7 @@ struct brcmf_sdio_hdrinfo { /* Private data for SDIO bus interaction */ struct brcmf_sdio { struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ - struct chip_info *ci; /* Chip info struct */ + struct brcmf_chip *ci; /* Chip info struct */ u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index d1de037..82bf3c5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -118,7 +118,7 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = { }; u8 -brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) +brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid) { u8 idx; @@ -131,7 +131,7 @@ brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid) static u32 brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct brcmf_chip *ci, u16 coreid) { u32 regdata; u8 idx; @@ -146,7 +146,7 @@ brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev, static u32 brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct brcmf_chip *ci, u16 coreid) { u8 idx; @@ -157,7 +157,7 @@ brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev, static bool brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct brcmf_chip *ci, u16 coreid) { u32 regdata; u8 idx; @@ -176,7 +176,7 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, static bool brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid) + struct brcmf_chip *ci, u16 coreid) { u32 regdata; u8 idx; @@ -200,7 +200,7 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 pre_resetbits, + struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits, u32 in_resetbits) { u32 regdata, base; @@ -287,7 +287,7 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 pre_resetbits, + struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits, u32 in_resetbits) { u8 idx; @@ -327,7 +327,7 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 pre_resetbits, + struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits, u32 in_resetbits, u32 post_resetbits) { u32 regdata; @@ -395,7 +395,7 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 pre_resetbits, + struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits, u32 in_resetbits, u32 post_resetbits) { u8 idx; @@ -425,7 +425,7 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, #ifdef DEBUG /* safety check for chipinfo */ -static int brcmf_sdio_chip_cichk(struct chip_info *ci) +static int brcmf_sdio_chip_cichk(struct brcmf_chip *ci) { u8 core_idx; @@ -452,14 +452,14 @@ static int brcmf_sdio_chip_cichk(struct chip_info *ci) return 0; } #else /* DEBUG */ -static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) +static inline int brcmf_sdio_chip_cichk(struct brcmf_chip *ci) { return 0; } #endif static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci) + struct brcmf_chip *ci) { u32 regdata; u32 socitype; @@ -708,7 +708,7 @@ brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev) static void brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci) + struct brcmf_chip *ci) { u32 base = ci->c_inf[0].base; @@ -743,15 +743,14 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, } int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, - struct chip_info **ci_ptr) + struct brcmf_chip **ci_ptr) { int ret; - struct chip_info *ci; + struct brcmf_chip *ci; brcmf_dbg(TRACE, "Enter\n"); - /* alloc chip_info_t */ - ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC); + ci = kzalloc(sizeof(*ci), GFP_ATOMIC); if (!ci) return -ENOMEM; @@ -779,7 +778,7 @@ err: } void -brcmf_sdio_chip_detach(struct chip_info **ci_ptr) +brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr) { brcmf_dbg(TRACE, "Enter\n"); @@ -798,7 +797,7 @@ static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len) void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u32 drivestrength) + struct brcmf_chip *ci, u32 drivestrength) { const struct sdiod_drive_str *str_tab = NULL; u32 str_mask; @@ -870,7 +869,7 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, static void brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci) + struct brcmf_chip *ci) { ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0); ci->resetcore(sdiodev, ci, BCMA_CORE_80211, @@ -879,8 +878,8 @@ brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0); } -static bool -brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) +static bool brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, + struct brcmf_chip *ci) { u8 core_idx; u32 reg_addr; @@ -903,7 +902,7 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) static inline void brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci) + struct brcmf_chip *ci) { u8 idx; u32 regdata; @@ -923,9 +922,8 @@ brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN); } -static bool -brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, - u32 rstvec) +static bool brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, + struct brcmf_chip *ci, u32 rstvec) { u8 core_idx; u32 reg_addr; @@ -948,7 +946,7 @@ brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, } void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci) + struct brcmf_chip *ci) { u8 arm_core_idx; @@ -962,7 +960,7 @@ void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, } bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u32 rstvec) + struct brcmf_chip *ci, u32 rstvec) { u8 arm_core_idx; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index a1aadf4..fb06143 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -54,7 +54,7 @@ #define BRCMF_MAX_CORENUM 6 -struct chip_core_info { +struct brcmf_core { u16 id; u16 rev; u32 base; @@ -63,27 +63,27 @@ struct chip_core_info { u32 cib; }; -struct chip_info { +struct brcmf_chip { u32 chip; u32 chiprev; /* core info */ /* always put chipcommon core at 0, bus core at 1 */ - struct chip_core_info c_inf[BRCMF_MAX_CORENUM]; + struct brcmf_core c_inf[BRCMF_MAX_CORENUM]; u32 pmurev; u32 pmucaps; u32 ramsize; u32 rambase; u32 rst_vec; /* reset vertor for ARM CR4 core */ - bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, + bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci, u16 coreid); - u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, + u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct brcmf_chip *ci, u16 coreid); void (*coredisable)(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 pre_resetbits, + struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits, u32 in_resetbits); void (*resetcore)(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u16 coreid, u32 pre_resetbits, + struct brcmf_chip *ci, u16 coreid, u32 pre_resetbits, u32 in_resetbits, u32 post_resetbits); }; @@ -217,14 +217,15 @@ struct sdpcmd_regs { }; int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, - struct chip_info **ci_ptr); -void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); + struct brcmf_chip **ci_ptr); +void brcmf_sdio_chip_detach(struct brcmf_chip **ci_ptr); void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u32 drivestrength); -u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); + struct brcmf_chip *ci, + u32 drivestrength); +u8 brcmf_sdio_chip_getinfidx(struct brcmf_chip *ci, u16 coreid); void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci); + struct brcmf_chip *ci); bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u32 rstvec); + struct brcmf_chip *ci, u32 rstvec); #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ -- cgit v1.1 From 2668b0b16cb555abe1b35a1c3cdeb482799fb7cb Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 13 Jan 2014 22:20:28 +0100 Subject: brcmfmac: initialize escan function pointer during scheduled scan For scheduled scan results the driver does a escan to obtain BSS details from the firmware. However, the escan uses a dynamically determined function. This needs to be set appropriately when handling scheduled scan results to avoid NULL pointer access. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Reviewed-by: Daniel (Deognyoun) Kim Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index aad83ae..d7718a5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2989,6 +2989,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, } set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + cfg->escan_info.run = brcmf_run_escan; err = brcmf_do_escan(cfg, wiphy, ifp, request); if (err) { clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); -- cgit v1.1 From bb350711ecb86568468b497d0ecd5c3fd7b45b1b Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Mon, 13 Jan 2014 22:20:29 +0100 Subject: brcmfmac: handle SDIO card removal When removing the card the driver still tries to access registers in the device. This patch adds another state for the bus that indicates the device is no longer reachable. This avoids errors accessing it while cleaning up the driver. Reviewed-by: Franky Lin Reviewed-by: Hante Meuleman Reviewed-by: Pieter-Paul Giesberts Signed-off-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 40 ++++--- drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | 21 ++++ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 120 +++++++++------------ drivers/net/wireless/brcm80211/brcmfmac/usb.c | 4 +- 5 files changed, 102 insertions(+), 87 deletions(-) (limited to 'drivers/net/wireless/brcm80211/brcmfmac') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 34c993d..fa35b23 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -287,6 +287,9 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, s32 retry = 0; int ret; + if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) + return -ENOMEDIUM; + /* * figure out how to read the register based on address range * 0x00 ~ 0x7FF: function 0 CCCR and FBR @@ -306,9 +309,12 @@ static int brcmf_sdiod_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, usleep_range(1000, 2000); ret = brcmf_sdiod_request_data(sdiodev, func_num, addr, regsz, data, write); - } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); + } while (ret != 0 && ret != -ENOMEDIUM && + retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); - if (ret != 0) + if (ret == -ENOMEDIUM) + brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); + else if (ret != 0) brcmf_err("failed with %d\n", ret); return ret; @@ -320,6 +326,9 @@ brcmf_sdiod_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) int err = 0, i; u8 addr[3]; + if (sdiodev->bus_if->state == BRCMF_BUS_NOMEDIUM) + return -ENOMEDIUM; + addr[0] = (address >> 8) & SBSDIO_SBADDRLOW_MASK; addr[1] = (address >> 16) & SBSDIO_SBADDRMID_MASK; addr[2] = (address >> 24) & SBSDIO_SBADDRHIGH_MASK; @@ -429,6 +438,7 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, bool write, u32 addr, struct sk_buff *pkt) { unsigned int req_sz; + int err; brcmf_sdiod_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); if (brcmf_sdiod_pm_resume_error(sdiodev)) @@ -439,18 +449,18 @@ static int brcmf_sdiod_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, req_sz &= (uint)~3; if (write) - return sdio_memcpy_toio(sdiodev->func[fn], addr, - ((u8 *)(pkt->data)), - req_sz); + err = sdio_memcpy_toio(sdiodev->func[fn], addr, + ((u8 *)(pkt->data)), req_sz); else if (fn == 1) - return sdio_memcpy_fromio(sdiodev->func[fn], - ((u8 *)(pkt->data)), - addr, req_sz); + err = sdio_memcpy_fromio(sdiodev->func[fn], ((u8 *)(pkt->data)), + addr, req_sz); else /* function 2 read is FIFO operation */ - return sdio_readsb(sdiodev->func[fn], - ((u8 *)(pkt->data)), addr, - req_sz); + err = sdio_readsb(sdiodev->func[fn], ((u8 *)(pkt->data)), addr, + req_sz); + if (err == -ENOMEDIUM) + brcmf_bus_change_state(sdiodev->bus_if, BRCMF_BUS_NOMEDIUM); + return err; } /** @@ -593,7 +603,11 @@ static int brcmf_sdiod_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; - if (ret != 0) { + if (ret == -ENOMEDIUM) { + brcmf_bus_change_state(sdiodev->bus_if, + BRCMF_BUS_NOMEDIUM); + break; + } else if (ret != 0) { brcmf_err("CMD53 sg block %s failed %d\n", write ? "write" : "read", ret); ret = -EIO; @@ -852,8 +866,6 @@ int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn) static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) { - sdiodev->bus_if->state = BRCMF_BUS_DOWN; - if (sdiodev->bus) { brcmf_sdio_remove(sdiodev->bus); sdiodev->bus = NULL; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 5c12a076..c453561 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -17,8 +17,12 @@ #ifndef _BRCMF_BUS_H_ #define _BRCMF_BUS_H_ +#include "dhd_dbg.h" + /* The level of bus communication with the dongle */ enum brcmf_bus_state { + BRCMF_BUS_UNKNOWN, /* Not determined yet */ + BRCMF_BUS_NOMEDIUM, /* No medium access to dongle */ BRCMF_BUS_DOWN, /* Not ready for frame transfers */ BRCMF_BUS_LOAD, /* Download access only (CPU reset) */ BRCMF_BUS_DATA /* Ready for frame transfers */ @@ -144,6 +148,23 @@ struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus) return bus->ops->gettxq(bus->dev); } + +static inline bool brcmf_bus_ready(struct brcmf_bus *bus) +{ + return bus->state == BRCMF_BUS_LOAD || bus->state == BRCMF_BUS_DATA; +} + +static inline void brcmf_bus_change_state(struct brcmf_bus *bus, + enum brcmf_bus_state new_state) +{ + /* NOMEDIUM is permanent */ + if (bus->state == BRCMF_BUS_NOMEDIUM) + return; + + brcmf_dbg(TRACE, "%d -> %d\n", bus->state, new_state); + bus->state = new_state; +} + /* * interface functions from common layer */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index af39eda..d4d966b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -934,7 +934,7 @@ int brcmf_bus_start(struct device *dev) p2p_ifp = NULL; /* signal bus ready */ - bus_if->state = BRCMF_BUS_DATA; + brcmf_bus_change_state(bus_if, BRCMF_BUS_DATA); /* Bus is ready, do any initialization */ ret = brcmf_c_preinit_dcmds(ifp); @@ -1029,6 +1029,8 @@ void brcmf_detach(struct device *dev) /* stop firmware event handling */ brcmf_fweh_detach(drvr); + brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); + /* make sure primary interface removed last */ for (i = BRCMF_MAX_IFS-1; i > -1; i--) if (drvr->iflist[i]) { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index ef24a1b..3e99189 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -1082,10 +1082,6 @@ static void brcmf_sdio_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) /* Clear partial in any case */ bus->cur_read.len = 0; - - /* If we can't reach the device, signal failure */ - if (err) - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } /* return total length of buffer chain */ @@ -1682,8 +1678,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) bus->rxpending = true; for (rd->seq_num = bus->rx_seq, rxleft = maxframes; - !bus->rxskip && rxleft && - bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN; + !bus->rxskip && rxleft && brcmf_bus_ready(bus->sdiodev->bus_if); rd->seq_num++, rxleft--) { /* Handle glomming separately */ @@ -2232,39 +2227,37 @@ static void brcmf_sdio_bus_stop(struct device *dev) bus->watchdog_tsk = NULL; } - sdio_claim_host(bus->sdiodev->func[1]); - - /* Enable clock for device interrupts */ - brcmf_sdio_bus_sleep(bus, false, false); + if (bus_if->state == BRCMF_BUS_DOWN) { + sdio_claim_host(sdiodev->func[1]); + + /* Enable clock for device interrupts */ + brcmf_sdio_bus_sleep(bus, false, false); + + /* Disable and clear interrupts at the chip level also */ + w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); + local_hostintmask = bus->hostintmask; + bus->hostintmask = 0; + + /* Force backplane clocks to assure F2 interrupt propagates */ + saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + &err); + if (!err) + brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + (saveclk | SBSDIO_FORCE_HT), &err); + if (err) + brcmf_err("Failed to force clock for F2: err %d\n", + err); - /* Disable and clear interrupts at the chip level also */ - w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask)); - local_hostintmask = bus->hostintmask; - bus->hostintmask = 0; + /* Turn off the bus (F2), free any pending packets */ + brcmf_dbg(INTR, "disable SDIO interrupts\n"); + sdio_disable_func(sdiodev->func[SDIO_FUNC_2]); - /* Change our idea of bus state */ - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; + /* Clear any pending interrupts now that F2 is disabled */ + w_sdreg32(bus, local_hostintmask, + offsetof(struct sdpcmd_regs, intstatus)); - /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = brcmf_sdiod_regrb(bus->sdiodev, - SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (!err) { - brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, - (saveclk | SBSDIO_FORCE_HT), &err); + sdio_release_host(sdiodev->func[1]); } - if (err) - brcmf_err("Failed to force clock for F2: err %d\n", err); - - /* Turn off the bus (F2), free any pending packets */ - brcmf_dbg(INTR, "disable SDIO interrupts\n"); - sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); - - /* Clear any pending interrupts now that F2 is disabled */ - w_sdreg32(bus, local_hostintmask, - offsetof(struct sdpcmd_regs, intstatus)); - - sdio_release_host(bus->sdiodev->func[1]); - /* Clear the data packet queues */ brcmu_pktq_flush(&bus->txq, true, NULL, NULL); @@ -2354,20 +2347,11 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) /* Check for inconsistent device control */ devctl = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err); - if (err) { - brcmf_err("error reading DEVCTL: %d\n", err); - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; - } #endif /* DEBUG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ clkctl = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, &err); - if (err) { - brcmf_err("error reading CSR: %d\n", - err); - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; - } brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", devctl, clkctl); @@ -2375,19 +2359,9 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) if (SBSDIO_HTAV(clkctl)) { devctl = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_DEVICE_CTL, &err); - if (err) { - brcmf_err("error reading DEVCTL: %d\n", - err); - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; - } devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL, devctl, &err); - if (err) { - brcmf_err("error writing DEVCTL: %d\n", - err); - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; - } bus->clkstate = CLK_AVAIL; } } @@ -2522,9 +2496,8 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) txlimit -= framecnt; } - if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) { + if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) { brcmf_err("failed backplane access over SDIO, halting operation\n"); - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; atomic_set(&bus->intstatus, 0); } else if (atomic_read(&bus->intstatus) || atomic_read(&bus->ipend) > 0 || @@ -3356,7 +3329,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus) } /* Allow HT Clock now that the ARM is running. */ - bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD; + brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_LOAD); bcmerror = 0; err: @@ -3633,7 +3606,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus) return; } - if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { + if (!brcmf_bus_ready(bus->sdiodev->bus_if)) { brcmf_err("bus is down. we have nothing to do\n"); return; } @@ -3644,7 +3617,6 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus) else if (brcmf_sdio_intr_rstatus(bus)) { brcmf_err("failed backplane access\n"); - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } /* Disable additional interrupts (is this needed now)? */ @@ -3781,6 +3753,11 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus) goto fail; } + /* SDIO register access works so moving + * state from UNKNOWN to DOWN. + */ + brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN); + if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) { brcmf_err("brcmf_sdio_chip_attach failed!\n"); goto fail; @@ -4004,7 +3981,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) /* Disable F2 to clear any intermediate frame state on the dongle */ sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]); - bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; bus->rxflow = false; /* Done with backplane-dependent accesses, can drop clock... */ @@ -4060,16 +4036,20 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) } if (bus->ci) { - sdio_claim_host(bus->sdiodev->func[1]); - brcmf_sdio_clkctl(bus, CLK_AVAIL, false); - /* Leave the device in state where it is 'quiet'. This - * is done by putting it in download_state which - * essentially resets all necessary cores - */ - msleep(20); - brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci); - brcmf_sdio_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); + if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) { + sdio_claim_host(bus->sdiodev->func[1]); + brcmf_sdio_clkctl(bus, CLK_AVAIL, false); + /* Leave the device in state where it is + * 'quiet'. This is done by putting it in + * download_state which essentially resets + * all necessary cores. + */ + msleep(20); + brcmf_sdio_chip_enter_download(bus->sdiodev, + bus->ci); + brcmf_sdio_clkctl(bus, CLK_NONE, false); + sdio_release_host(bus->sdiodev->func[1]); + } brcmf_sdio_chip_detach(&bus->ci); } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index c345c32..24f65cd 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -522,10 +522,10 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) /* update state of upper layer */ if (state == BRCMFMAC_USB_STATE_DOWN) { brcmf_dbg(USB, "DBUS is down\n"); - bcmf_bus->state = BRCMF_BUS_DOWN; + brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DOWN); } else if (state == BRCMFMAC_USB_STATE_UP) { brcmf_dbg(USB, "DBUS is up\n"); - bcmf_bus->state = BRCMF_BUS_DATA; + brcmf_bus_change_state(bcmf_bus, BRCMF_BUS_DATA); } else { brcmf_dbg(USB, "DBUS current state=%d\n", state); } -- cgit v1.1