brcmfmac: bcm4354 support and cleanup
Subsystems (2)
cover brcmfmac: bcm4354 support and cleanup
This series contains support for new 2x2 11ac device. Other patches are minor issues that and/or cleanup.
This series is intended for v3.15 kernel and applies to the master branch of the wireless-next repository.
Arend van Spriel (2):
brcmfmac: assure active clock request upon entering SLEEP state
brcmfmac: remove mode field from brcmf_cfg80211_vif structure
Franky Lin (1):
brcmfmac: add BCM4354 SDIO interface support
Hante Meuleman (2):
brcmfmac: Protect tx seq number for data and control
brcmfmac: Improve scanning settings for connect.
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 1 + drivers/net/wireless/brcm80211/brcmfmac/chip.c | 5 + drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 260 +++++++++++--------- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 6 +- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 94 +++---- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 17 -- .../net/wireless/brcm80211/include/brcm_hw_ids.h | 1 + include/linux/mmc/sdio_ids.h | 1 + 8 files changed, 191 insertions(+), 194 deletions(-)
Signature · 1 line
1.7.9.5
PATCH 1/5 brcmfmac: add BCM4354 SDIO interface support
From: Franky Lin <[email protected]>
BCM4354 is an a/b/g/n/ac 2x2 WiFi chip. This patch adds support for it through SDIO interface.
--- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 1 + drivers/net/wireless/brcm80211/brcmfmac/chip.c | 5 +++++ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 7 ++++++- .../net/wireless/brcm80211/include/brcm_hw_ids.h | 1 + include/linux/mmc/sdio_ids.h | 1 + 5 files changed, 14 insertions(+), 1 deletion(-)
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +1 -0
@@ -988,6 +988,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43362)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4335_4339)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4354)}, { /* end: all zeroes */ }, };MODULE_DEVICE_TABLE (sdio, brcmf_sdmmc_ids);
drivers/net/wireless/brcm80211/brcmfmac/chip.c +5 -0
@@ -504,6 +504,7 @@ static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) ci->pub.ramsize =0x3c000 ;break ;case BCM4339_CHIP_ID : +case BCM4354_CHIP_ID : ci->pub.ramsize =0xc0000 ; ci->pub.rambase =0x180000 ;break ;
@@ -1006,6 +1007,10 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub) chip = container_of(pub, struct brcmf_chip_priv, pub);switch (pub->chip) { +case BCM4354_CHIP_ID : +/* explicitly check SR engine enable bit */ + pmu_cc3_mask =BIT (2 ); +/* fall-through */ case BCM43241_CHIP_ID :case BCM4335_CHIP_ID :case BCM4339_CHIP_ID :
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +6 -1
@@ -578,6 +578,8 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" +#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" +#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt"MODULE_FIRMWARE (BCM43143_FIRMWARE_NAME );MODULE_FIRMWARE (BCM43143_NVRAM_NAME );
@@ -597,6 +599,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);MODULE_FIRMWARE (BCM43362_NVRAM_NAME );MODULE_FIRMWARE (BCM4339_FIRMWARE_NAME );MODULE_FIRMWARE (BCM4339_NVRAM_NAME ); +MODULE_FIRMWARE (BCM4354_FIRMWARE_NAME ); +MODULE_FIRMWARE (BCM4354_NVRAM_NAME );struct brcmf_firmware_names {u32 chipid;
@@ -622,7 +626,8 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = { { 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) } + { BCM4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, + { BCM4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } };
drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +1 -0
@@ -43,5 +43,6 @@#define BCM4335_CHIP_ID 0x4335#define BCM43362_CHIP_ID 43362#define BCM4339_CHIP_ID 0x4339 +#define BCM4354_CHIP_ID 0x4354#endif /* _BRCM_HW_IDS_H_ */
include/linux/mmc/sdio_ids.h +1 -0
@@ -31,6 +31,7 @@#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335#define SDIO_DEVICE_ID_BROADCOM_43362 43362 +#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354#define SDIO_VENDOR_ID_INTEL 0x0089#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402
Signature · 1 line
1.7.9.5
PATCH 2/5 brcmfmac: Protect tx seq number for data and control
In reply to Arend van SprielFrom: Hante Meuleman <[email protected]>
SDIO tx uses a sequence number which is common for data and control. This requires that access to this sequence number is protected. A mutex was used to achieve this, but it also required the reordering of code for tx control.
--- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 214 ++++++++++---------- 1 file changed, 108 insertions(+), 106 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +108 -106
@@ -458,10 +458,11 @@ struct brcmf_sdio {bool alp_only;/* Don't use HT clock (ALP only) */ u8 *ctrl_frame_buf; -u32 ctrl_frame_len; +u16 ctrl_frame_len;bool ctrl_frame_stat; -spinlock_t txqlock; +spinlock_t txq_lock;/* protect bus->txq */ +struct semaphore tx_seq_lock;/* protect bus->tx_seq */ wait_queue_head_t ctrl_wait;wait_queue_head_t dcmd_resp_wait;
@@ -2316,13 +2317,15 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)/* Send frames until the limit or some other event */ for (cnt =0 ; (cnt < maxframes) &&data_ok (bus);) { pkt_num =1 ; -__skb_queue_head_init (&pktq); +if (down_interruptible (&bus->tx_seq_lock)) +return cnt;if (bus->txglom) pkt_num =min_t (u8, bus->tx_max - bus->tx_seq, bus->sdiodev->txglomsz); pkt_num =min_t (u32, pkt_num,brcmu_pktq_mlen (&bus->txq, ~bus->flowcontrol)); -spin_lock_bh (&bus->txqlock); +__skb_queue_head_init (&pktq); +spin_lock_bh (&bus->txq_lock);for (i =0 ; i < pkt_num; i++) { pkt =brcmu_pktq_mdeq (&bus->txq, tx_prec_map, &prec_out);
@@ -2330,11 +2333,15 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)break ;__skb_queue_tail (&pktq, pkt); } -spin_unlock_bh (&bus->txqlock); -if (i ==0 ) +spin_unlock_bh (&bus->txq_lock); +if (i ==0 ) { +up (&bus->tx_seq_lock);break ; + } ret =brcmf_sdio_txpkt (bus, &pktq,SDPCM_DATA_CHANNEL ); +up (&bus->tx_seq_lock); + cnt += i;/* In poll mode, need to check for other events */
@@ -2363,6 +2370,68 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)return cnt; } +static int brcmf_sdio_tx_ctrlframe (struct brcmf_sdio *bus,u8 *frame,u16 len) +{ +u8 doff; +u16 pad; +uint retries =0 ; +struct brcmf_sdio_hdrinfo hd_info = {0 }; +int ret; + +brcmf_dbg (TRACE ,"Enter\n" ); + +/* Back the pointer to make room for bus header */ + frame -= bus->tx_hdrlen; + len += bus->tx_hdrlen; + +/* Add alignment padding (optional for ctl frames) */ + doff = ((unsigned long )frame % bus->head_align); +if (doff) { + frame -= doff; + len += doff; +memset (frame + bus->tx_hdrlen,0 , doff); + } + +/* Round send length to next SDIO block */ + pad =0 ; +if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { + pad = bus->blocksize - (len % bus->blocksize); +if ((pad > bus->roundup) || (pad >= bus->blocksize)) + pad =0 ; + }else if (len % bus->head_align) { + pad = bus->head_align - (len % bus->head_align); + } + len += pad; + + hd_info.len = len - pad; + hd_info.channel =SDPCM_CONTROL_CHANNEL ; + hd_info.dat_offset = doff + bus->tx_hdrlen; + hd_info.seq_num = bus->tx_seq; + 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); + +brcmf_dbg_hex_dump (BRCMF_BYTES_ON () &&BRCMF_CTL_ON (), + frame, len,"Tx Frame:\n" ); +brcmf_dbg_hex_dump (!(BRCMF_BYTES_ON () &&BRCMF_CTL_ON ()) && +BRCMF_HDRS_ON (), + frame,min_t (u16, len,16 ),"TxHdr:\n" ); + +do { + ret =brcmf_sdiod_send_buf (bus->sdiodev, frame, len); + +if (ret <0 ) +brcmf_sdio_txfail (bus); +else + bus->tx_seq = (bus->tx_seq +1 ) %SDPCM_SEQ_WRAP ; + }while (ret <0 && retries++ <TXRETRIES ); + +return ret; +} +static void brcmf_sdio_bus_stop (struct device *dev) {u32 local_hostintmask;
@@ -2596,26 +2665,23 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)brcmf_sdio_clrintr (bus); -if (data_ok (bus) && bus->ctrl_frame_stat && - (bus->clkstate ==CLK_AVAIL )) { - -sdio_claim_host (bus->sdiodev->func[1 ]); - err =brcmf_sdiod_send_buf (bus->sdiodev, bus->ctrl_frame_buf, - (u32 )bus->ctrl_frame_len); - -if (err <0 ) -brcmf_sdio_txfail (bus); -else - bus->tx_seq = (bus->tx_seq +1 ) %SDPCM_SEQ_WRAP ; +if (bus->ctrl_frame_stat && (bus->clkstate ==CLK_AVAIL ) && + (down_interruptible (&bus->tx_seq_lock) ==0 )) { +if (data_ok (bus)) { +sdio_claim_host (bus->sdiodev->func[1 ]); + err =brcmf_sdio_tx_ctrlframe (bus, bus->ctrl_frame_buf, + bus->ctrl_frame_len); +sdio_release_host (bus->sdiodev->func[1 ]); -sdio_release_host (bus->sdiodev->func[1 ]); - bus->ctrl_frame_stat = false; -brcmf_sdio_wait_event_wakeup (bus); + bus->ctrl_frame_stat = false; +brcmf_sdio_wait_event_wakeup (bus); + } +up (&bus->tx_seq_lock); }/* Send queued frames (limit 1 if rx may still be pending) */ -else if ((bus->clkstate ==CLK_AVAIL ) && !atomic_read (&bus->fcstate) && -brcmu_pktq_mlen (&bus->txq, ~bus->flowcontrol) && txlimit - &&data_ok (bus)) { +if ((bus->clkstate ==CLK_AVAIL ) && !atomic_read (&bus->fcstate) && +brcmu_pktq_mlen (&bus->txq, ~bus->flowcontrol) && txlimit && +data_ok (bus)) { framecnt = bus->rxpending ?min (txlimit, bus->txminmax) : txlimit;brcmf_sdio_sendfromq (bus, framecnt);
@@ -2649,7 +2715,6 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)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; -ulong flags;brcmf_dbg (TRACE ,"Enter: pkt: data %p len %d\n" , pkt->data, pkt->len);
@@ -2665,7 +2730,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) bus->sdcnt.fcqueued++;/* Priority based enq */ -spin_lock_irqsave (&bus->txqlock, flags); +spin_lock_bh (&bus->txq_lock);/* reset bus_flags in packet cb */ *(u16 *)(pkt->cb) =0 ;if (!brcmf_c_prec_enq (bus->sdiodev->dev, &bus->txq, pkt, prec)) {
@@ -2680,7 +2745,7 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt) bus->txoff = true;brcmf_txflowblock (bus->sdiodev->dev, true); } -spin_unlock_irqrestore (&bus->txqlock, flags); +spin_unlock_bh (&bus->txq_lock);#ifdef DEBUG if (pktq_plen (&bus->txq, prec) > qcount[prec])
@@ -2775,87 +2840,27 @@ break2: }#endif /* DEBUG */ -static int brcmf_sdio_tx_frame (struct brcmf_sdio *bus,u8 *frame,u16 len) -{ -int ret; - - bus->ctrl_frame_stat = false; - ret =brcmf_sdiod_send_buf (bus->sdiodev, frame, len); - -if (ret <0 ) -brcmf_sdio_txfail (bus); -else - bus->tx_seq = (bus->tx_seq +1 ) %SDPCM_SEQ_WRAP ; - -return ret; -} -static int brcmf_sdio_bus_txctl (struct device *dev,unsigned char *msg,uint msglen) { -u8 *frame; -u16 len, pad; -uint retries =0 ; -u8 doff =0 ; -int ret =-1 ;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; -struct brcmf_sdio_hdrinfo hd_info = {0 }; +int ret =-1 ;brcmf_dbg (TRACE ,"Enter\n" ); -/* Back the pointer to make a room for bus header */ - frame = msg - bus->tx_hdrlen; - len = (msglen += bus->tx_hdrlen); - -/* Add alignment padding (optional for ctl frames) */ - doff = ((unsigned long )frame % bus->head_align); -if (doff) { - frame -= doff; - len += doff; - msglen += doff; -memset (frame,0 , doff + bus->tx_hdrlen); - } -/* precondition: doff < bus->head_align */ - doff += bus->tx_hdrlen; - -/* Round send length to next SDIO block */ - pad =0 ; -if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { - pad = bus->blocksize - (len % bus->blocksize); -if ((pad > bus->roundup) || (pad >= bus->blocksize)) - pad =0 ; - }else if (len % bus->head_align) { - pad = bus->head_align - (len % bus->head_align); - } - len += pad; - -/* precondition: IS_ALIGNED((unsigned long)frame, 2) */ - -/* Make sure backplane clock is on */ -sdio_claim_host (bus->sdiodev->func[1 ]); -brcmf_sdio_bus_sleep (bus, false, false); -sdio_release_host (bus->sdiodev->func[1 ]); - - hd_info.len = (u16 )msglen; - hd_info.channel =SDPCM_CONTROL_CHANNEL ; - hd_info.dat_offset = doff; - hd_info.seq_num = bus->tx_seq; - 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 (down_interruptible (&bus->tx_seq_lock)) +return -EINTR ;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); - bus->ctrl_frame_stat = true; +up (&bus->tx_seq_lock);/* Send from dpc */ - bus->ctrl_frame_buf = frame; - bus->ctrl_frame_len = len; + bus->ctrl_frame_buf = msg; + bus->ctrl_frame_len = msglen; + bus->ctrl_frame_stat = true; wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
@@ -2866,22 +2871,18 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) ret =0 ; }else {brcmf_dbg (SDIO ,"ctrl_frame_stat == true\n" ); + bus->ctrl_frame_stat = false; +if (down_interruptible (&bus->tx_seq_lock)) +return -EINTR ; ret =-1 ; } } -if (ret ==-1 ) { -brcmf_dbg_hex_dump (BRCMF_BYTES_ON () &&BRCMF_CTL_ON (), - frame, len,"Tx Frame:\n" ); -brcmf_dbg_hex_dump (!(BRCMF_BYTES_ON () &&BRCMF_CTL_ON ()) && -BRCMF_HDRS_ON (), - frame,min_t (u16, len,16 ),"TxHdr:\n" ); - -do { -sdio_claim_host (bus->sdiodev->func[1 ]); - ret =brcmf_sdio_tx_frame (bus, frame, len); -sdio_release_host (bus->sdiodev->func[1 ]); - }while (ret <0 && retries++ <TXRETRIES ); +sdio_claim_host (bus->sdiodev->func[1 ]); +brcmf_sdio_bus_sleep (bus, false, false); + ret =brcmf_sdio_tx_ctrlframe (bus, msg, msglen); +sdio_release_host (bus->sdiodev->func[1 ]); +up (&bus->tx_seq_lock); }if (ret)
@@ -4052,7 +4053,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) }spin_lock_init (&bus->rxctl_lock); -spin_lock_init (&bus->txqlock); +spin_lock_init (&bus->txq_lock); +sema_init (&bus->tx_seq_lock,1 );init_waitqueue_head (&bus->ctrl_wait);init_waitqueue_head (&bus->dcmd_resp_wait);
Signature · 1 line
1.7.9.5
PATCH 3/5 brcmfmac: Improve scanning settings for connect.
In reply to Arend van SprielFrom: Hante Meuleman <[email protected]>
When connecting without specifying the channel it can take quite some time to connect. This is because not all parameters for the scan operation are set to optimized values. This patch changes these parameters resulting in a much faster connect in certain situations.
--- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 34 ++++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +20 -14
@@ -1682,22 +1682,9 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, ext_join_params->ssid_le.SSID_len =cpu_to_le32 (profile->ssid.SSID_len);memcpy (&ext_join_params->ssid_le.SSID, sme->ssid, profile->ssid.SSID_len); -/*increase dwell time to receive probe response or detect Beacon -* from target AP at a noisy air only during connect command -*/ - ext_join_params->scan_le.active_time = -cpu_to_le32 (BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS ); - ext_join_params->scan_le.passive_time = -cpu_to_le32 (BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS ); +/* Set up join scan parameters */ ext_join_params->scan_le.scan_type =-1 ; -/* to sync with presence period of VSDB GO. -* Send probe request more frequently. Probe request will be stopped -* when it gets probe response from target AP/GO. -*/ - ext_join_params->scan_le.nprobes = -cpu_to_le32 (BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS / -BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS ); ext_join_params->scan_le.home_time =cpu_to_le32 (-1 );if (sme->bssid)
@@ -1710,6 +1697,25 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, ext_join_params->assoc_le.chanspec_list[0 ] =cpu_to_le16 (chanspec); +/* Increase dwell time to receive probe response or detect +* beacon from target AP at a noisy air only during connect +* command. +*/ + ext_join_params->scan_le.active_time = +cpu_to_le32 (BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS ); + ext_join_params->scan_le.passive_time = +cpu_to_le32 (BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS ); +/* To sync with presence period of VSDB GO send probe request +* more frequently. Probe request will be stopped when it gets +* probe response from target AP/GO. +*/ + ext_join_params->scan_le.nprobes = +cpu_to_le32 (BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS / +BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS ); + }else { + ext_join_params->scan_le.active_time =cpu_to_le32 (-1 ); + ext_join_params->scan_le.passive_time =cpu_to_le32 (-1 ); + ext_join_params->scan_le.nprobes =cpu_to_le32 (-1 ); } err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
Signature · 1 line
1.7.9.5
PATCH 4/5 brcmfmac: assure active clock request upon entering SLEEP state
In reply to Arend van SprielWhen the SDIO driver goes in low power state it must assure that a clock request in ChipCLKCSR is set. Otherwise waking up the device can fail. The register is read and if necessary the ALP clock will be requested.
--- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 39 ++++++++++++++------ 1 file changed, 28 insertions(+), 11 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +28 -11
@@ -175,6 +175,7 @@ struct rte_console {#define SBSDIO_ALP_AVAIL 0x40/* Status: HT is ready */ #define SBSDIO_HT_AVAIL 0x80 +#define SBSDIO_CSR_MASK 0x1F#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL)#define SBSDIO_ALPAV (regval) ((regval) & SBSDIO_AVBITS)#define SBSDIO_HTAV (regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS)
@@ -720,16 +721,12 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on)int err =0 ;int try_cnt =0 ; -brcmf_dbg (TRACE ,"Enter\n" ); +brcmf_dbg (TRACE ,"Enter: on=%d\n" , on); wr_val = (on <<SBSDIO_FUNC1_SLEEPCSR_KSO_SHIFT );/* 1st KSO write goes to AOS wake up core if device is asleep */ 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; - }if (on) {/* device WAKEUP through KSO:
@@ -759,13 +756,19 @@ brcmf_sdio_kso_control(struct brcmf_sdio *bus, bool on) &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_sdiod_regwb (bus->sdiodev,SBSDIO_FUNC1_SLEEPCSR , wr_val, &err); }while (try_cnt++ <MAX_KSO_ATTEMPTS ); +if (try_cnt >2 ) +brcmf_dbg (SDIO ,"try_cnt=%d rd_val=0x%x err=%d\n" , try_cnt, + rd_val, err); + +if (try_cnt >MAX_KSO_ATTEMPTS ) +brcmf_err ("max tries: rd_val=0x%x err=%d\n" , rd_val, err); +return err; }
@@ -966,6 +969,7 @@ static int brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) { int err = 0; +u8 clkcsr; brcmf_dbg(SDIO, "Enter: request %s currently %s\n", (sleep ? "SLEEP" : "WAKE"),
@@ -984,8 +988,20 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) atomic_read(&bus->ipend) > 0 || (!atomic_read(&bus->fcstate) && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && - data_ok(bus))) - return -EBUSY; + data_ok(bus))) { + err = -EBUSY ; + goto done; + } + + clkcsr =brcmf_sdiod_regrb (bus->sdiodev, +SBSDIO_FUNC1_CHIPCLKCSR , + &err); +if ((clkcsr &SBSDIO_CSR_MASK ) ==0 ) { +brcmf_dbg (SDIO ,"no clock, set ALP\n" ); +brcmf_sdiod_regwb (bus->sdiodev, +SBSDIO_FUNC1_CHIPCLKCSR , +SBSDIO_ALP_AVAIL_REQ , &err); + } err =brcmf_sdio_kso_control (bus, false);/* disable watchdog */ if (!err)
@@ -1002,7 +1018,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok) }else {brcmf_err ("error while changing bus sleep state %d\n" , err); -return err; + goto done; } }
@@ -1014,7 +1030,8 @@ end: }else {brcmf_sdio_clkctl (bus,CLK_AVAIL , pendok); } - +done: +brcmf_dbg (SDIO ,"Exit: err=%d\n" , err);return err; }
Signature · 1 line
1.7.9.5
PATCH 5/5 brcmfmac: remove mode field from brcmf_cfg80211_vif structure
In reply to Arend van SprielThe nl80211 iftype was converted to a mode value and stored in brcmf_cfg80211_vif structure. The value was used only within brcmfmac driver to decide execution of conditional code. Better use wireless_dev::iftype for that as the wdev is contained in the brcmf_cfg80211_vif structure.
--- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 6 +- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 60 +++++++------------- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 17 ------ 3 files changed, 21 insertions(+), 62 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/p2p.c +2 -4
@@ -797,7 +797,8 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg,/* SOCIAL CHANNELS 1, 6, 11 */ search_state =WL_P2P_DISC_ST_SEARCH ;brcmf_dbg (INFO ,"P2P SEARCH PHASE START\n" ); - }else if (dev !=NULL && vif->mode ==WL_MODE_AP ) { + }else if (dev !=NULL && + vif->wdev.iftype ==NL80211_IFTYPE_P2P_GO ) {/* If you are already a GO, then do SEARCH only */ brcmf_dbg (INFO ,"Already a GO. Do SEARCH Only\n" ); search_state =WL_P2P_DISC_ST_SEARCH ;
@@ -2256,7 +2257,6 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,struct brcmf_if *ifp =netdev_priv (cfg_to_ndev (cfg));struct brcmf_cfg80211_vif *vif;enum brcmf_fil_p2p_if_types iftype; -enum wl_mode mode;int err;if (brcmf_cfg80211_vif_event_armed (cfg))
@@ -2267,11 +2267,9 @@ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,switch (type) {case NL80211_IFTYPE_P2P_CLIENT : iftype =BRCMF_FIL_P2P_IF_CLIENT ; - mode =WL_MODE_BSS ;break ;case NL80211_IFTYPE_P2P_GO : iftype =BRCMF_FIL_P2P_IF_GO ; - mode =WL_MODE_AP ;break ;case NL80211_IFTYPE_P2P_DEVICE : return brcmf_p2p_create_p2pdev(&cfg->p2p, wiphy,
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +19 -41
136 lines not on this page · raw message
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +0 -17
@@ -89,21 +89,6 @@ enum brcmf_scan_status { BRCMF_SCAN_STATUS_SUPPRESS, }; -/** -* enum wl_mode - driver mode of virtual interface. -* -* @WL_MODE_BSS: connects to BSS. -* @WL_MODE_IBSS: operate as ad-hoc. -* @WL_MODE_AP: operate as access-point. -* @WL_MODE_P2P: provide P2P discovery. -*/ -enum wl_mode { -WL_MODE_BSS , -WL_MODE_IBSS , -WL_MODE_AP , -WL_MODE_P2P -}; -/* dongle configuration */ struct brcmf_cfg80211_conf {u32 frag_threshold;
@@ -193,7 +178,6 @@ struct vif_saved_ie {* @ifp: lower layer interface pointer * @wdev: wireless device. * @profile: profile information. -* @mode: operating mode. * @roam_off: roaming state. * @sme_state: SME state using enum brcmf_vif_status bits. * @pm_block: power-management blocked.
@@ -204,7 +188,6 @@ struct brcmf_cfg80211_vif {struct brcmf_if *ifp;struct wireless_dev wdev;struct brcmf_cfg80211_profile profile; -s32 mode;s32 roam_off;unsigned long sme_state;bool pm_block;
Signature · 1 line
1.7.9.5