mac80211: update brcmfmac including missing boardrev workaround
[openwrt.git] / package / kernel / mac80211 / patches / 309-02-brcmfmac-fix-sdio-sg-table-alloc-crash.patch
1 From: Hante Meuleman <meuleman@broadcom.com>
2 Date: Tue, 19 Jan 2016 12:39:24 +0100
3 Subject: [PATCH] brcmfmac: fix sdio sg table alloc crash
4
5 With commit 7d34b0560567 ("brcmfmac: Move all module parameters to
6 one place") a bug was introduced causing a null pointer exception.
7 This patch fixes the bug by initializing the sg table till after
8 the settings have been initialized.
9
10 Fixes: 7d34b0560567 ("brcmfmac: Move all module parameters to one place")
11 Reported-by: Marc Zyngier <marc.zyngier@arm.com>
12 Tested-by: Marc Zyngier <marc.zyngier@arm.com>
13 Reviewed-by: Arend Van Spriel <arend@broadcom.com>
14 Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
15 Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
16 Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
17 Signed-off-by: Arend van Spriel <arend@broadcom.com>
18 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
19 ---
20
21 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
22 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
23 @@ -879,11 +879,24 @@ int brcmf_sdiod_abort(struct brcmf_sdio_
24         return 0;
25  }
26  
27 -static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
28 +void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
29  {
30 +       struct sdio_func *func;
31 +       struct mmc_host *host;
32 +       uint max_blocks;
33         uint nents;
34         int err;
35  
36 +       func = sdiodev->func[2];
37 +       host = func->card->host;
38 +       sdiodev->sg_support = host->max_segs > 1;
39 +       max_blocks = min_t(uint, host->max_blk_count, 511u);
40 +       sdiodev->max_request_size = min_t(uint, host->max_req_size,
41 +                                         max_blocks * func->cur_blksize);
42 +       sdiodev->max_segment_count = min_t(uint, host->max_segs,
43 +                                          SG_MAX_SINGLE_ALLOC);
44 +       sdiodev->max_segment_size = host->max_seg_size;
45 +
46         if (!sdiodev->sg_support)
47                 return;
48  
49 @@ -1021,9 +1034,6 @@ static void brcmf_sdiod_host_fixup(struc
50  
51  static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
52  {
53 -       struct sdio_func *func;
54 -       struct mmc_host *host;
55 -       uint max_blocks;
56         int ret = 0;
57  
58         sdiodev->num_funcs = 2;
59 @@ -1054,26 +1064,6 @@ static int brcmf_sdiod_probe(struct brcm
60                 goto out;
61         }
62  
63 -       /*
64 -        * determine host related variables after brcmf_sdiod_probe()
65 -        * as func->cur_blksize is properly set and F2 init has been
66 -        * completed successfully.
67 -        */
68 -       func = sdiodev->func[2];
69 -       host = func->card->host;
70 -       sdiodev->sg_support = host->max_segs > 1;
71 -       max_blocks = min_t(uint, host->max_blk_count, 511u);
72 -       sdiodev->max_request_size = min_t(uint, host->max_req_size,
73 -                                         max_blocks * func->cur_blksize);
74 -       sdiodev->max_segment_count = min_t(uint, host->max_segs,
75 -                                          SG_MAX_SINGLE_ALLOC);
76 -       sdiodev->max_segment_size = host->max_seg_size;
77 -
78 -       /* allocate scatter-gather table. sg support
79 -        * will be disabled upon allocation failure.
80 -        */
81 -       brcmf_sdiod_sgtable_alloc(sdiodev);
82 -
83         ret = brcmf_sdiod_freezer_attach(sdiodev);
84         if (ret)
85                 goto out;
86 @@ -1084,7 +1074,7 @@ static int brcmf_sdiod_probe(struct brcm
87                 ret = -ENODEV;
88                 goto out;
89         }
90 -       brcmf_sdiod_host_fixup(host);
91 +       brcmf_sdiod_host_fixup(sdiodev->func[2]->card->host);
92  out:
93         if (ret)
94                 brcmf_sdiod_remove(sdiodev);
95 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
96 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
97 @@ -4114,6 +4114,11 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
98                 goto fail;
99         }
100  
101 +       /* allocate scatter-gather table. sg support
102 +        * will be disabled upon allocation failure.
103 +        */
104 +       brcmf_sdiod_sgtable_alloc(bus->sdiodev);
105 +
106         /* Query the F2 block size, set roundup accordingly */
107         bus->blocksize = bus->sdiodev->func[2]->cur_blksize;
108         bus->roundup = min(max_roundup, bus->blocksize);
109 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
110 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
111 @@ -342,6 +342,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_
112  
113  /* Issue an abort to the specified function */
114  int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
115 +void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev);
116  void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev,
117                               enum brcmf_sdiod_state state);
118  #ifdef CONFIG_PM_SLEEP