image.mk: fix emitting profiles for targets that have no subtargets
[openwrt/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