17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/types.h>
20 #include <linux/kernel.h>
24 #include <linux/netdevice.h>
26 #include <linux/sched.h>
32 #include <linux/module.h>
36 #include <asm/unaligned.h>
45 #define DCMD_RESP_TIMEOUT 2000
49 #define BRCMF_TRAP_INFO_SIZE 80
51 #define CBUF_LEN (128)
54 #define CONSOLE_BUFFER_MAX 2024
82 struct rte_log_le log_le;
101 #define TXHI (TXQLEN - 256)
102 #define TXLOW (TXHI - 256)
107 #define BRCMF_RXBOUND 50
110 #define BRCMF_TXBOUND 20
113 #define BRCMF_TXMINMAX 1
115 #define MEMBLOCK 2048
117 #define MAX_DATA_BUF (32 * 1024)
120 #define BRCMF_FIRSTREAD (1 << 6)
126 #define SBSDIO_DEVCTL_SETBUSY 0x01
128 #define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02
130 #define SBSDIO_DEVCTL_CA_INT_ONLY 0x04
133 #define SBSDIO_DEVCTL_PADS_ISO 0x08
135 #define SBSDIO_DEVCTL_SB_RST_CTL 0x30
137 #define SBSDIO_DEVCTL_RST_CORECTL 0x00
139 #define SBSDIO_DEVCTL_RST_BPRESET 0x10
141 #define SBSDIO_DEVCTL_RST_NOBPRESET 0x20
146 #define SBSDIO_CIS_BASE_COMMON 0x1000
148 #define SBSDIO_CIS_SIZE_LIMIT 0x200
150 #define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF
153 #define SBSDIO_CIS_MANFID_TUPLE_LEN 6
156 #define I_SMB_SW0 (1 << 0)
157 #define I_SMB_SW1 (1 << 1)
158 #define I_SMB_SW2 (1 << 2)
159 #define I_SMB_SW3 (1 << 3)
160 #define I_SMB_SW_MASK 0x0000000f
161 #define I_SMB_SW_SHIFT 0
162 #define I_HMB_SW0 (1 << 4)
163 #define I_HMB_SW1 (1 << 5)
164 #define I_HMB_SW2 (1 << 6)
165 #define I_HMB_SW3 (1 << 7)
166 #define I_HMB_SW_MASK 0x000000f0
167 #define I_HMB_SW_SHIFT 4
168 #define I_WR_OOSYNC (1 << 8)
169 #define I_RD_OOSYNC (1 << 9)
170 #define I_PC (1 << 10)
171 #define I_PD (1 << 11)
172 #define I_DE (1 << 12)
173 #define I_RU (1 << 13)
174 #define I_RO (1 << 14)
175 #define I_XU (1 << 15)
176 #define I_RI (1 << 16)
177 #define I_BUSPWR (1 << 17)
178 #define I_XMTDATA_AVAIL (1 << 23)
179 #define I_XI (1 << 24)
180 #define I_RF_TERM (1 << 25)
181 #define I_WF_TERM (1 << 26)
182 #define I_PCMCIA_XU (1 << 27)
183 #define I_SBINT (1 << 28)
184 #define I_CHIPACTIVE (1 << 29)
185 #define I_SRESET (1 << 30)
186 #define I_IOE2 (1U << 31)
187 #define I_ERRORS (I_PC | I_PD | I_DE | I_RU | I_RO | I_XU)
188 #define I_DMA (I_RI | I_XI | I_ERRORS)
191 #define CC_CISRDY (1 << 0)
192 #define CC_BPRESEN (1 << 1)
193 #define CC_F2RDY (1 << 2)
194 #define CC_CLRPADSISO (1 << 3)
195 #define CC_XMTDATAAVAIL_MODE (1 << 4)
196 #define CC_XMTDATAAVAIL_CTRL (1 << 5)
199 #define SFC_RF_TERM (1 << 0)
200 #define SFC_WF_TERM (1 << 1)
201 #define SFC_CRC4WOOS (1 << 2)
202 #define SFC_ABORTALL (1 << 3)
205 #define SDPCM_FRAMETAG_LEN 4
208 #define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
209 #define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN)
216 #define SMB_NAK (1 << 0)
217 #define SMB_INT_ACK (1 << 1)
218 #define SMB_USE_OOB (1 << 2)
219 #define SMB_DEV_INT (1 << 3)
222 #define SMB_DATA_VERSION_SHIFT 16
229 #define I_HMB_FC_STATE I_HMB_SW0
230 #define I_HMB_FC_CHANGE I_HMB_SW1
231 #define I_HMB_FRAME_IND I_HMB_SW2
232 #define I_HMB_HOST_INT I_HMB_SW3
235 #define HMB_DATA_NAKHANDLED 1
236 #define HMB_DATA_DEVREADY 2
237 #define HMB_DATA_FC 4
238 #define HMB_DATA_FWREADY 8
240 #define HMB_DATA_FCDATA_MASK 0xff000000
241 #define HMB_DATA_FCDATA_SHIFT 24
243 #define HMB_DATA_VERSION_MASK 0x00ff0000
244 #define HMB_DATA_VERSION_SHIFT 16
251 #define SDPCM_PROT_VERSION 4
254 #define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff)
256 #define SDPCM_CHANNEL_MASK 0x00000f00
257 #define SDPCM_CHANNEL_SHIFT 8
258 #define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f)
260 #define SDPCM_NEXTLEN_OFFSET 2
263 #define SDPCM_DOFFSET_OFFSET 3
264 #define SDPCM_DOFFSET_VALUE(p) (((u8 *)p)[SDPCM_DOFFSET_OFFSET] & 0xff)
265 #define SDPCM_DOFFSET_MASK 0xff000000
266 #define SDPCM_DOFFSET_SHIFT 24
267 #define SDPCM_FCMASK_OFFSET 4
268 #define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
269 #define SDPCM_WINDOW_OFFSET 5
270 #define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
272 #define SDPCM_SWHEADER_LEN 8
275 #define SDPCM_CONTROL_CHANNEL 0
276 #define SDPCM_EVENT_CHANNEL 1
277 #define SDPCM_DATA_CHANNEL 2
278 #define SDPCM_GLOM_CHANNEL 3
279 #define SDPCM_TEST_CHANNEL 15
281 #define SDPCM_SEQUENCE_WRAP 256
283 #define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80)
289 #define SDPCM_SHARED_VERSION 0x0003
290 #define SDPCM_SHARED_VERSION_MASK 0x00FF
291 #define SDPCM_SHARED_ASSERT_BUILT 0x0100
292 #define SDPCM_SHARED_ASSERT 0x0200
293 #define SDPCM_SHARED_TRAP 0x0400
296 #define MAX_HDR_READ (1 << 6)
297 #define MAX_RX_DATASZ 2048
300 #define BRCMF_WAIT_F2RDY 3000
307 #undef PMU_MAX_TRANSITION_DLY
308 #define PMU_MAX_TRANSITION_DLY 1000000
311 #define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \
312 SBSDIO_ALP_AVAIL_REQ)
315 #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
317 #define BRCMF_SDIO_FW_NAME "brcm/brcmfmac-sdio.bin"
318 #define BRCMF_SDIO_NV_NAME "brcm/brcmfmac-sdio.txt"
322 #define BRCMF_IDLE_IMMEDIATE (-1)
323 #define BRCMF_IDLE_ACTIVE 0
326 #define BRCMF_IDLE_INTERVAL 1
428 struct brcmf_console {
431 struct rte_log_le log_le;
437 struct brcmf_trap_info {
499 struct chip_info *
ci;
597 #define CLK_PENDING 2
605 #define SDIO_DRIVE_STRENGTH 6
607 #define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL)
610 static const uint retry_limit = 2;
613 static const uint max_roundup = 512;
620 datalign = (
unsigned long)(p->
data);
621 datalign =
roundup(datalign, (align)) - datalign;
645 bus->
ci->c_inf[idx].base + offset, &ret);
657 bus->
ci->c_inf[idx].base + reg_offset,
663 #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND)
665 #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
668 static int brcmf_sdbrcm_htclk(
struct brcmf_sdio *bus,
bool on,
bool pendok)
671 u8 clkctl, clkreq, devctl;
785 static int brcmf_sdbrcm_sdclk(
struct brcmf_sdio *bus,
bool on)
819 brcmf_sdbrcm_sdclk(bus,
true);
821 brcmf_sdbrcm_htclk(bus,
true, pendok);
829 brcmf_sdbrcm_sdclk(bus,
true);
831 brcmf_sdbrcm_htclk(bus,
false,
false);
841 brcmf_sdbrcm_htclk(bus,
false,
false);
843 brcmf_sdbrcm_sdclk(bus,
false);
864 ret = r_sdreg32(bus, &hmb_data,
870 bus->
sdcnt.f1regdata += 2;
874 brcmf_dbg(
INFO,
"Dongle reports NAK handled, expect rtx of %d\n",
909 bus->
sdcnt.fc_xoff++;
914 bus->
sdcnt.fc_rcvd++;
920 HMB_DATA_NAKHANDLED |
930 static void brcmf_sdbrcm_rxfail(
struct brcmf_sdio *bus,
bool abort,
bool rtx)
938 abort ?
"abort command, " :
"",
939 rtx ?
", send NAK" :
"");
946 bus->
sdcnt.f1regdata++;
949 for (lastrbc = retries = 0xffff; retries > 0; retries--) {
954 bus->
sdcnt.f1regdata += 2;
956 if ((hi == 0) && (lo == 0))
959 if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) {
961 lastrbc, (hi << 8) + lo);
963 lastrbc = (hi << 8) + lo;
969 brcmf_dbg(
INFO,
"flush took %d iterations\n", 0xffff - retries);
976 bus->
sdcnt.f1regdata++;
999 skb_queue_walk(&bus->
glom, p) {
1019 skb_queue_walk(&bus->
glom, p)
1028 skb_queue_walk_safe(&bus->glom, cur, next) {
1038 u8 rx_seq,
fc, tx_seq_max;
1045 len = get_unaligned_le16(header);
1046 checksum = get_unaligned_le16(header +
sizeof(
u16));
1048 if (!(len | checksum)) {
1052 if ((
u16)(~(len ^ checksum))) {
1054 bus->
sdcnt.rx_badhdr++;
1055 brcmf_sdbrcm_rxfail(bus,
false,
false);
1078 bus->
sdiodev->bus_if->dstats.rx_errors++;
1079 bus->
sdcnt.rx_toolong++;
1080 brcmf_sdbrcm_rxfail(bus,
false,
false);
1087 bus->
sdcnt.rx_badhdr++;
1088 brcmf_sdbrcm_rxfail(bus,
false,
false);
1095 bus->
sdcnt.rx_badseq++;
1108 bus->
sdcnt.fc_xoff++;
1110 bus->
sdcnt.fc_xon++;
1111 bus->
sdcnt.fc_rcvd++;
1115 if ((
u8)(tx_seq_max - bus->
tx_seq) > 0x40) {
1117 tx_seq_max = bus->
tx_seq + 2;
1119 bus->
tx_max = tx_seq_max;
1130 struct sk_buff *pfirst, *pnext;
1148 pfirst = pnext =
NULL;
1150 dptr = bus->
glomd->data;
1151 if (!dlen || (dlen & 1)) {
1157 for (totlen = num = 0;
dlen; num++) {
1159 sublen = get_unaligned_le16(dptr);
1160 dlen -=
sizeof(
u16);
1161 dptr +=
sizeof(
u16);
1171 sublen, BRCMF_SDALIGN);
1186 if (pnext ==
NULL) {
1194 pkt_align(pnext, sublen, BRCMF_SDALIGN);
1200 brcmf_dbg(GLOM,
"allocated %d-byte packet chain for %d subframes\n",
1204 brcmf_dbg(GLOM,
"glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
1207 pfirst = pnext =
NULL;
1209 brcmf_sdbrcm_free_glom(bus);
1221 if (!skb_queue_empty(&bus->
glom)) {
1223 brcmf_dbg(GLOM,
"try superframe read, packet chain:\n");
1224 skb_queue_walk(&bus->
glom, pnext) {
1225 brcmf_dbg(GLOM,
" %p: %p len 0x%04x (%d)\n",
1226 pnext, (
u8 *) (pnext->
data),
1231 pfirst = skb_peek(&bus->
glom);
1232 dlen = (
u16) brcmf_sdbrcm_glom_len(bus);
1247 sublen = (
u16) brcmf_sdbrcm_glom_from_buf(bus, dlen);
1248 if (sublen != dlen) {
1259 bus->
sdcnt.f2rxdata++;
1265 bus->
sdiodev->bus_if->dstats.rx_errors++;
1268 brcmf_sdbrcm_rxfail(bus,
true,
true);
1271 brcmf_sdbrcm_rxfail(bus,
true,
false);
1272 bus->
sdcnt.rxglomfail++;
1273 brcmf_sdbrcm_free_glom(bus);
1283 dptr = (
u8 *) (pfirst->
data);
1284 sublen = get_unaligned_le16(dptr);
1285 check = get_unaligned_le16(dptr +
sizeof(
u16));
1300 if ((
u16)~(sublen ^ check)) {
1301 brcmf_dbg(
ERROR,
"(superframe): HW hdr error: len/check 0x%04x/0x%04x\n",
1305 brcmf_dbg(
ERROR,
"(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n",
1313 &dptr[SDPCM_FRAMETAG_LEN]));
1320 brcmf_dbg(
ERROR,
"(superframe): Bad data offset %d: HW %d pkt %d min %d\n",
1329 bus->
sdcnt.rx_badseq++;
1334 if ((
u8) (txmax - bus->
tx_seq) > 0x40) {
1347 skb_queue_walk(&bus->
glom, pnext) {
1352 dptr = (
u8 *) (pnext->
data);
1353 dlen = (
u16) (pnext->
len);
1354 sublen = get_unaligned_le16(dptr);
1355 check = get_unaligned_le16(dptr +
sizeof(
u16));
1359 dptr, 32,
"subframe:\n");
1361 if ((
u16)~(sublen ^ check)) {
1362 brcmf_dbg(
ERROR,
"(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n",
1363 num, sublen, check);
1365 }
else if ((sublen > dlen) || (sublen <
SDPCM_HDRLEN)) {
1366 brcmf_dbg(
ERROR,
"(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n",
1375 brcmf_dbg(
ERROR,
"(subframe %d): Bad data offset %d: HW %d min %d\n",
1389 brcmf_sdbrcm_rxfail(bus,
true,
true);
1392 brcmf_sdbrcm_rxfail(bus,
true,
false);
1393 bus->
sdcnt.rxglomfail++;
1394 brcmf_sdbrcm_free_glom(bus);
1402 skb_queue_walk_safe(&bus->
glom, pfirst, pnext) {
1403 dptr = (
u8 *) (pfirst->
data);
1404 sublen = get_unaligned_le16(dptr);
1409 brcmf_dbg(GLOM,
"Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n",
1410 num, pfirst, pfirst->
data,
1411 pfirst->
len, sublen, chan, seq);
1417 brcmf_dbg(GLOM,
"rx_seq %d, expected %d\n",
1419 bus->
sdcnt.rx_badseq++;
1425 dptr, dlen,
"Rx Subframe Data:\n");
1427 __skb_trim(pfirst, sublen);
1430 if (pfirst->
len == 0) {
1435 &ifidx, pfirst) != 0) {
1437 bus->
sdiodev->bus_if->dstats.rx_errors++;
1446 "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n",
1447 bus->
glom.qlen, pfirst, pfirst->
data,
1452 if (bus->
glom.qlen) {
1458 bus->
sdcnt.rxglomframes++;
1459 bus->
sdcnt.rxglompkts += bus->
glom.qlen;
1464 static int brcmf_sdbrcm_dcmd_resp_wait(
struct brcmf_sdio *bus,
uint *condition,
1474 while (!(*condition) && (!signal_pending(
current) && timeout))
1486 static int brcmf_sdbrcm_dcmd_resp_wake(
struct brcmf_sdio *bus)
1505 pad = ((
unsigned long)bus->
rxctl % BRCMF_SDALIGN);
1507 bus->
rxctl += (BRCMF_SDALIGN -
pad);
1520 ((len + pad) < bus->
sdiodev->bus_if->maxctl))
1522 }
else if (rdlen % BRCMF_SDALIGN) {
1531 if ((rdlen + BRCMF_FIRSTREAD) > bus->
sdiodev->bus_if->maxctl) {
1532 brcmf_dbg(
ERROR,
"%d-byte control read exceeds %d-byte buffer\n",
1533 rdlen, bus->
sdiodev->bus_if->maxctl);
1534 bus->
sdiodev->bus_if->dstats.rx_errors++;
1535 brcmf_sdbrcm_rxfail(bus,
false,
false);
1539 if ((len - doff) > bus->
sdiodev->bus_if->maxctl) {
1540 brcmf_dbg(
ERROR,
"%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n",
1541 len, len - doff, bus->
sdiodev->bus_if->maxctl);
1542 bus->
sdiodev->bus_if->dstats.rx_errors++;
1543 bus->
sdcnt.rx_toolong++;
1544 brcmf_sdbrcm_rxfail(bus,
false,
false);
1553 bus->
sdcnt.f2rxdata++;
1559 bus->
sdcnt.rxc_errors++;
1560 brcmf_sdbrcm_rxfail(bus,
true,
true);
1567 bus->
rxctl, len,
"RxCtrl:\n");
1571 bus->
rxlen = len - doff;
1575 brcmf_sdbrcm_dcmd_resp_wake(bus);
1583 if (*pad <= bus->roundup && *pad < bus->blocksize &&
1586 }
else if (*rdlen % BRCMF_SDALIGN) {
1608 !bus->
rxskip && rxleft &&
1613 if (bus->
glomd || !skb_queue_empty(&bus->
glom)) {
1615 brcmf_dbg(GLOM,
"calling rxglom: glomd %p, glom %p\n",
1617 cnt = brcmf_sdbrcm_rxglom(bus, rd->
seq_num);
1618 brcmf_dbg(GLOM,
"rxglom returned %d\n", cnt);
1620 rxleft = (rxleft >
cnt) ? (rxleft - cnt) : 1;
1632 bus->
sdcnt.f2rxhdrs++;
1636 bus->
sdcnt.rx_hdrfail++;
1637 brcmf_sdbrcm_rxfail(bus,
true,
true);
1645 if (!brcmf_sdio_hdparser(bus, bus->
rxhdr, rd)) {
1653 brcmf_sdbrcm_read_control(bus, bus->
rxhdr,
1664 rd->
len - BRCMF_FIRSTREAD : 0;
1668 brcmf_pad(bus, &pad, &rd->
len_left);
1675 bus->
sdiodev->bus_if->dstats.rx_dropped++;
1676 brcmf_sdbrcm_rxfail(bus,
false,
1681 pkt_align(pkt, rd->
len_left, BRCMF_SDALIGN);
1685 bus->
sdcnt.f2rxdata++;
1691 bus->
sdiodev->bus_if->dstats.rx_errors++;
1692 brcmf_sdbrcm_rxfail(bus,
true,
1704 if (!brcmf_sdio_hdparser(bus, bus->
rxhdr, &rd_new)) {
1708 bus->
sdcnt.rx_readahead_cnt++;
1709 if (rd->
len != roundup(rd_new.len, 16)) {
1710 brcmf_dbg(
ERROR,
"frame length mismatch:read %d, should be %d\n",
1712 roundup(rd_new.len, 16) >> 4);
1714 brcmf_sdbrcm_rxfail(bus,
true,
true);
1733 brcmf_sdbrcm_rxfail(bus,
false,
true);
1740 pkt->
data, rd->
len,
"Rx Data:\n");
1745 brcmf_dbg(GLOM,
"glom descriptor, %d bytes:\n",
1750 __skb_trim(pkt, rd->
len);
1755 "descriptor!\n", __func__);
1756 brcmf_sdbrcm_rxfail(bus,
false,
false);
1767 __skb_trim(pkt, rd->
len);
1776 if (pkt->
len == 0) {
1783 bus->
sdiodev->bus_if->dstats.rx_errors++;
1789 brcmf_rx_packet(bus->
sdiodev->dev, ifidx, pkt);
1793 rxcount = maxframes - rxleft;
1808 brcmf_sdbrcm_wait_for_event(
struct brcmf_sdio *bus,
bool *lockvar)
1817 brcmf_sdbrcm_wait_event_wakeup(
struct brcmf_sdio *bus)
1827 uint chan,
bool free_pkt)
1838 frame = (
u8 *) (pkt->
data);
1841 pad = ((
unsigned long)frame % BRCMF_SDALIGN);
1843 if (skb_headroom(pkt) <
pad) {
1845 skb_headroom(pkt), pad);
1846 bus->
sdiodev->bus_if->tx_realloc++;
1850 pkt->
len + BRCMF_SDALIGN);
1855 pkt_align(
new, pkt->
len, BRCMF_SDALIGN);
1862 frame = (
u8 *) (pkt->
data);
1867 frame = (
u8 *) (pkt->
data);
1895 frame, len,
"Tx Frame:\n");
1902 frame,
min_t(
u16, len, 16),
"TxHdr:\n");
1907 if ((pad <= bus->roundup) && (pad < bus->
blocksize))
1909 }
else if (len % BRCMF_SDALIGN) {
1919 bus->
sdcnt.f2txdata++;
1923 brcmf_dbg(
INFO,
"sdio error %d, abort command and terminate frame\n",
1925 bus->
sdcnt.tx_sderrs++;
1930 bus->
sdcnt.f1regdata++;
1932 for (i = 0; i < 3; i++) {
1938 bus->
sdcnt.f1regdata += 2;
1939 if ((hi == 0) && (lo == 0))
1964 int ret = 0, prec_out;
1974 for (cnt = 0; (cnt < maxframes) && data_ok(bus); cnt++) {
1978 spin_unlock_bh(&bus->
txqlock);
1981 spin_unlock_bh(&bus->
txqlock);
1986 bus->
sdiodev->bus_if->dstats.tx_errors++;
1991 if (!bus->
intr && cnt) {
1993 ret = r_sdreg32(bus, &intstatus,
1996 bus->
sdcnt.f2txdata++;
2005 if (bus->
sdiodev->bus_if->drvr_up &&
2015 static void brcmf_sdbrcm_bus_stop(
struct device *
dev)
2017 u32 local_hostintmask;
2035 brcmf_sdbrcm_clkctl(bus,
CLK_AVAIL,
false);
2061 w_sdreg32(bus, local_hostintmask,
2073 brcmf_sdbrcm_free_glom(bus);
2077 brcmf_sdbrcm_dcmd_resp_wake(bus);
2086 #ifdef CONFIG_BRCMFMAC_SDIO_OOB
2087 static inline void brcmf_sdbrcm_clrintr(
struct brcmf_sdio *bus)
2089 unsigned long flags;
2096 spin_unlock_irqrestore(&bus->
sdiodev->irq_en_lock, flags);
2099 static inline void brcmf_sdbrcm_clrintr(
struct brcmf_sdio *bus)
2104 static inline void brcmf_sdbrcm_adddpctsk(
struct brcmf_sdio *bus)
2107 unsigned long flags;
2121 static int brcmf_sdio_intr_rstatus(
struct brcmf_sdio *bus)
2129 addr = bus->
ci->c_inf[
idx].base +
2133 bus->
sdcnt.f1regdata++;
2143 bus->
sdcnt.f1regdata++;
2159 unsigned long intstatus;
2160 uint rxlimit = bus->rxbound;
2161 uint txlimit = bus->txbound;
2171 u8 clkctl, devctl = 0;
2192 brcmf_dbg(
INFO,
"DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",
2216 brcmf_sdbrcm_clkctl(bus,
CLK_AVAIL,
true);
2222 err = brcmf_sdio_intr_rstatus(bus);
2234 intstatus &= ~I_HMB_FC_CHANGE;
2235 err = w_sdreg32(bus, I_HMB_FC_CHANGE,
2238 err = r_sdreg32(bus, &newstatus,
2240 bus->sdcnt.f1regdata += 2;
2243 intstatus |= (newstatus & bus->hostintmask);
2248 intstatus &= ~I_HMB_HOST_INT;
2249 intstatus |= brcmf_sdbrcm_hostmail(bus);
2255 intstatus &= ~I_WR_OOSYNC;
2260 intstatus &= ~I_RD_OOSYNC;
2265 intstatus &= ~I_SBINT;
2271 intstatus &= ~I_CHIPACTIVE;
2280 framecnt = brcmf_sdio_readframes(bus, rxlimit);
2281 if (!bus->rxpending)
2283 rxlimit -=
min(framecnt, rxlimit);
2289 set_bit(n, (
unsigned long *)&bus->intstatus.counter);
2292 brcmf_sdbrcm_clrintr(bus);
2294 if (data_ok(bus) && bus->ctrl_frame_stat &&
2300 (
u32) bus->ctrl_frame_len);
2305 brcmf_dbg(
INFO,
"sdio error %d, abort command and terminate frame\n",
2307 bus->sdcnt.tx_sderrs++;
2313 bus->sdcnt.f1regdata++;
2315 for (i = 0; i < 3; i++) {
2323 bus->sdcnt.f1regdata += 2;
2324 if ((hi == 0) && (lo == 0))
2331 bus->ctrl_frame_stat =
false;
2332 brcmf_sdbrcm_wait_event_wakeup(bus);
2335 else if ((bus->clkstate == CLK_AVAIL) && !
atomic_read(&bus->fcstate) &&
2338 framecnt = bus->rxpending ?
min(txlimit, bus->txminmax) :
2340 framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
2341 txlimit -= framecnt;
2344 if ((bus->sdiodev->bus_if->state ==
BRCMF_BUS_DOWN) || (err != 0)) {
2345 brcmf_dbg(
ERROR,
"failed backplane access over SDIO, halting operation\n");
2353 brcmf_sdbrcm_adddpctsk(bus);
2359 bus->activity =
false;
2360 brcmf_sdbrcm_clkctl(bus,
CLK_NONE,
false);
2366 static int brcmf_sdbrcm_bus_txdata(
struct device *dev,
struct sk_buff *pkt)
2373 unsigned long flags;
2388 bus->
sdcnt.fcqueued++;
2401 spin_unlock_bh(&bus->
txqlock);
2403 if (pktq_len(&bus->
txq) >=
TXHI) {
2409 if (pktq_plen(&bus->
txq, prec) > qcount[prec])
2410 qcount[prec] = pktq_plen(&bus->
txq, prec);
2417 brcmf_sdbrcm_adddpctsk(bus);
2452 brcmf_dbg(
INFO,
"%s %d bytes at offset 0x%08x in window 0x%08x\n",
2453 write ?
"write" :
"read", dsize,
2454 sdaddr, address & SBSDIO_SBWINDOW_MASK);
2456 sdaddr, data, dsize);
2490 #define CONSOLE_LINE_MAX 192
2492 static int brcmf_sdbrcm_readconsole(
struct brcmf_sdio *bus)
2494 struct brcmf_console *
c = &bus->console;
2495 u8 line[CONSOLE_LINE_MAX], ch;
2500 if (bus->console_addr == 0)
2504 addr = bus->console_addr +
offsetof(
struct rte_console, log_le);
2505 rv = brcmf_sdbrcm_membytes(bus,
false, addr, (
u8 *)&c->log_le,
2511 if (c->buf ==
NULL) {
2521 if (idx > c->bufsize)
2531 rv = brcmf_sdbrcm_membytes(bus,
false, addr, c->buf, c->bufsize);
2535 while (c->last != idx) {
2536 for (n = 0; n < CONSOLE_LINE_MAX - 2; n++) {
2537 if (c->last == idx) {
2546 c->last = c->bufsize -
n;
2549 ch = c->buf[c->last];
2550 c->last = (c->last + 1) % c->bufsize;
2557 if (line[n - 1] ==
'\r')
2580 brcmf_dbg(
INFO,
"sdio error %d, abort command and terminate frame\n",
2582 bus->
sdcnt.tx_sderrs++;
2588 bus->
sdcnt.f1regdata++;
2590 for (i = 0; i < 3; i++) {
2596 bus->
sdcnt.f1regdata += 2;
2597 if (hi == 0 && lo == 0)
2620 unsigned long flags;
2629 doff = ((
unsigned long)frame % BRCMF_SDALIGN);
2634 memset(frame, 0, doff + SDPCM_HDRLEN);
2642 if ((pad <= bus->roundup) && (pad < bus->
blocksize))
2644 }
else if (len % BRCMF_SDALIGN) {
2658 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL,
false);
2673 if (!data_ok(bus)) {
2674 brcmf_dbg(
INFO,
"No bus credit bus->tx_max %d, bus->tx_seq %d\n",
2694 frame, len,
"Tx Frame:\n");
2697 frame,
min_t(
u16, len, 16),
"TxHdr:\n");
2700 ret = brcmf_tx_frame(bus, frame, len);
2701 }
while (ret < 0 && retries++ <
TXRETRIES);
2710 brcmf_sdbrcm_clkctl(bus,
CLK_NONE,
true);
2718 bus->
sdcnt.tx_ctlerrs++;
2720 bus->
sdcnt.tx_ctlpkts++;
2722 return ret ? -
EIO : 0;
2726 static inline bool brcmf_sdio_valid_shared_address(
u32 addr)
2728 return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff));
2731 static int brcmf_sdio_readshared(
struct brcmf_sdio *bus,
2746 rv = brcmf_sdbrcm_membytes(bus,
false, shaddr,
2759 if (!brcmf_sdio_valid_shared_address(addr)) {
2766 rv = brcmf_sdbrcm_membytes(bus,
false, addr, (
u8 *)&sh_le,
2782 "sdpcm_shared version mismatch: dhd %d dongle %d\n",
2791 static int brcmf_sdio_dump_console(
struct brcmf_sdio *bus,
2795 u32 addr, console_ptr, console_size, console_index;
2796 char *conbuf =
NULL;
2804 rv = brcmf_sdbrcm_membytes(bus,
false, addr,
2805 (
u8 *)&sh_val,
sizeof(
u32));
2811 rv = brcmf_sdbrcm_membytes(bus,
false, addr,
2812 (
u8 *)&sh_val,
sizeof(
u32));
2818 rv = brcmf_sdbrcm_membytes(bus,
false, addr,
2819 (
u8 *)&sh_val,
sizeof(
u32));
2825 if (console_size <= CONSOLE_BUFFER_MAX)
2826 conbuf =
vzalloc(console_size+1);
2832 conbuf[console_size] =
'\0';
2833 rv = brcmf_sdbrcm_membytes(bus,
false, console_ptr, (
u8 *)conbuf,
2839 conbuf + console_index,
2840 console_size - console_index);
2845 if (console_index > 0) {
2848 conbuf, console_index - 1);
2859 char __user *data,
size_t count)
2863 struct brcmf_trap_info
tr;
2870 error = brcmf_sdbrcm_membytes(bus,
false, sh->
trap_addr, (
u8 *)&
tr,
2871 sizeof(
struct brcmf_trap_info));
2875 nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
2880 "dongle trap info: type 0x%x @ epc 0x%08x\n"
2881 " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
2882 " lr 0x%08x pc 0x%08x offset 0x%x\n"
2883 " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n"
2884 " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n",
2902 static int brcmf_sdio_assert_info(
struct brcmf_sdio *bus,
2908 char file[80] =
"?";
2909 char expr[80] =
"<???>";
2935 "dongle assert: %s:%d: assert(%s)\n",
2940 static int brcmf_sdbrcm_checkdied(
struct brcmf_sdio *bus)
2946 error = brcmf_sdio_readshared(bus, &sh);
2963 static int brcmf_sdbrcm_died_dump(
struct brcmf_sdio *bus,
char __user *data,
2964 size_t count, loff_t *ppos)
2975 error = brcmf_sdio_readshared(bus, &sh);
2979 error = brcmf_sdio_assert_info(bus, &sh, data, count);
2984 error = brcmf_sdio_trap_info(bus, &sh, data, count);
2995 static ssize_t brcmf_sdio_forensic_read(
struct file *
f,
char __user *data,
2996 size_t count, loff_t *ppos)
3001 res = brcmf_sdbrcm_died_dump(bus, data, count, ppos);
3010 .read = brcmf_sdio_forensic_read
3013 static void brcmf_sdio_debugfs_create(
struct brcmf_sdio *bus)
3018 if (IS_ERR_OR_NULL(dentry))
3022 &brcmf_sdio_forensic_ops);
3026 static int brcmf_sdbrcm_checkdied(
struct brcmf_sdio *bus)
3031 static void brcmf_sdio_debugfs_create(
struct brcmf_sdio *bus)
3037 brcmf_sdbrcm_bus_rxctl(
struct device *dev,
unsigned char *msg,
uint msglen)
3049 timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->
rxlen, &pending);
3058 brcmf_dbg(
CTL,
"resumed on rxctl frame, got %d expected %d\n",
3060 }
else if (timeleft == 0) {
3062 brcmf_sdbrcm_checkdied(bus);
3063 }
else if (pending) {
3068 brcmf_sdbrcm_checkdied(bus);
3072 bus->
sdcnt.rx_ctlpkts++;
3074 bus->
sdcnt.rx_ctlerrs++;
3079 static int brcmf_sdbrcm_write_vars(
struct brcmf_sdio *bus)
3086 char *nvram_ularray;
3095 bcmerror = brcmf_sdbrcm_membytes(bus,
true, varaddr,
3109 bcmerror = brcmf_sdbrcm_membytes(bus,
false, varaddr,
3110 nvram_ularray, bus->
varsz);
3112 brcmf_dbg(
ERROR,
"error %d on reading %d nvram bytes at 0x%08x\n",
3113 bcmerror, bus->
varsz, varaddr);
3121 kfree(nvram_ularray);
3128 varaddr, bus->
varsz);
3139 varsizew = bus->
varsz / 4;
3140 varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF);
3145 bus->
varsz, varsizew);
3148 bcmerror = brcmf_sdbrcm_membytes(bus,
true, (bus->
ramsize - 4),
3149 (
u8 *)&varsizew_le, 4);
3154 static int brcmf_sdbrcm_download_state(
struct brcmf_sdio *bus,
bool enter)
3157 struct chip_info *ci = bus->
ci;
3172 brcmf_sdbrcm_membytes(bus,
true, bus->
ramsize - 4,
3182 bcmerror = brcmf_sdbrcm_write_vars(bus);
3188 w_sdreg32(bus, 0xFFFFFFFF,
3202 static int brcmf_sdbrcm_get_image(
char *buf,
int len,
struct brcmf_sdio *bus)
3212 static int brcmf_sdbrcm_download_code_file(
struct brcmf_sdio *bus)
3230 if (memblock ==
NULL) {
3234 if ((
u32)(
unsigned long)memblock % BRCMF_SDALIGN)
3235 memptr += (BRCMF_SDALIGN -
3241 ret = brcmf_sdbrcm_membytes(bus,
true, offset, memptr, len);
3244 ret, MEMBLOCK, offset);
3269 static int brcmf_process_nvram_vars(
struct brcmf_sdio *bus)
3276 uint buf_len,
n, len;
3286 findNewline =
false;
3289 for (n = 0; n < len; n++) {
3292 if (varbuf[n] ==
'\r')
3294 if (findNewline && varbuf[n] !=
'\n')
3296 findNewline =
false;
3297 if (varbuf[n] ==
'#') {
3301 if (varbuf[n] ==
'\n') {
3311 buf_len = dp - varbuf;
3312 while (dp < varbuf + n)
3327 bus->
vars[buf_len] = 0;
3333 static int brcmf_sdbrcm_download_nvram(
struct brcmf_sdio *bus)
3337 if (bus->
sdiodev->bus_if->drvr_up)
3347 ret = brcmf_process_nvram_vars(bus);
3354 static int _brcmf_sdbrcm_download_firmware(
struct brcmf_sdio *bus)
3359 if (brcmf_sdbrcm_download_state(bus,
true)) {
3365 if (brcmf_sdbrcm_download_code_file(bus)) {
3371 if (brcmf_sdbrcm_download_nvram(bus))
3375 if (brcmf_sdbrcm_download_state(bus,
false)) {
3387 brcmf_sdbrcm_download_firmware(
struct brcmf_sdio *bus)
3392 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL,
false);
3394 ret = _brcmf_sdbrcm_download_firmware(bus) == 0;
3401 static int brcmf_sdbrcm_bus_init(
struct device *dev)
3406 unsigned long timeout;
3415 if (!(brcmf_sdbrcm_download_firmware(bus)))
3419 if (!bus->
sdiodev->bus_if->drvr)
3423 bus->
sdcnt.tickcnt = 0;
3429 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL,
false);
3454 while (enable != ready) {
3464 brcmf_dbg(
INFO,
"enable 0x%02x, ready 0x%02x\n", enable, ready);
3467 if (ready == enable) {
3492 brcmf_sdbrcm_clkctl(bus,
CLK_NONE,
false);
3516 bus->
sdcnt.intrcount++;
3520 if (brcmf_sdio_intr_rstatus(bus)) {
3529 brcmf_sdbrcm_adddpctsk(bus);
3533 static bool brcmf_sdbrcm_bus_watchdog(
struct brcmf_sdio *bus)
3538 unsigned long flags;
3553 (bus->
sdcnt.intrcount == bus->
sdcnt.lastintrs)) {
3574 bus->
sdcnt.pollcnt++;
3577 brcmf_sdbrcm_adddpctsk(bus);
3588 bus->console_interval != 0) {
3590 if (bus->console.count >= bus->console_interval) {
3591 bus->console.count -= bus->console_interval;
3593 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL,
false);
3594 if (brcmf_sdbrcm_readconsole(bus) < 0)
3596 bus->console_interval = 0;
3609 brcmf_sdbrcm_clkctl(bus,
CLK_NONE,
false);
3619 static bool brcmf_sdbrcm_chipmatch(
u16 chipid)
3637 unsigned long flags;
3643 brcmf_sdbrcm_dpc(bus);
3652 static void brcmf_sdbrcm_release_malloc(
struct brcmf_sdio *bus)
3664 static bool brcmf_sdbrcm_probe_malloc(
struct brcmf_sdio *bus)
3668 if (bus->
sdiodev->bus_if->maxctl) {
3687 if ((
unsigned long)bus->
databuf % BRCMF_SDALIGN)
3700 brcmf_sdbrcm_probe_attach(
struct brcmf_sdio *bus,
u32 regsva)
3710 pr_debug(
"F1 signature read @0x18000000=0x%4x\n",
3725 brcmf_dbg(
ERROR,
"ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n",
3735 if (!brcmf_sdbrcm_chipmatch((
u16) bus->
ci->chip)) {
3752 reg_addr = bus->
ci->c_inf[
idx].base +
3775 static bool brcmf_sdbrcm_probe_init(
struct brcmf_sdio *bus)
3806 brcmf_sdbrcm_watchdog_thread(
void *data)
3816 brcmf_sdbrcm_bus_watchdog(bus);
3818 bus->
sdcnt.tickcnt++;
3826 brcmf_sdbrcm_watchdog(
unsigned long data)
3839 static void brcmf_sdbrcm_release_dongle(
struct brcmf_sdio *bus)
3844 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL,
false);
3845 brcmf_sdbrcm_clkctl(bus,
CLK_NONE,
false);
3856 static void brcmf_sdbrcm_release(
struct brcmf_sdio *bus)
3867 if (bus->
sdiodev->bus_if->drvr) {
3869 brcmf_sdbrcm_release_dongle(bus);
3872 brcmf_sdbrcm_release_malloc(bus);
3886 u32 dngl_txglomalign;
3901 skb_queue_head_init(&bus->
glom);
3908 if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
3927 bus->
timer.function = brcmf_sdbrcm_watchdog;
3930 sema_init(&bus->
sdsem, 1);
3935 bus,
"brcmf_watchdog");
3937 pr_warn(
"brcmf_watchdog thread failed to start\n");
3945 bus->
sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop;
3946 bus->
sdiodev->bus_if->brcmf_bus_init = brcmf_sdbrcm_bus_init;
3947 bus->
sdiodev->bus_if->brcmf_bus_txdata = brcmf_sdbrcm_bus_txdata;
3948 bus->
sdiodev->bus_if->brcmf_bus_txctl = brcmf_sdbrcm_bus_txctl;
3949 bus->
sdiodev->bus_if->brcmf_bus_rxctl = brcmf_sdbrcm_bus_rxctl;
3958 if (!(brcmf_sdbrcm_probe_malloc(bus))) {
3963 if (!(brcmf_sdbrcm_probe_init(bus))) {
3968 brcmf_sdio_debugfs_create(bus);
3975 if (bus->
ci->c_inf[idx].rev < 12) {
3978 dlst->
name =
"bus:txglom";
3979 dlst->
param = (
char *)&dngl_txglom;
3983 dngl_txglomalign = bus->
sdiodev->bus_if->align;
3984 dlst->
name =
"bus:txglomalign";
3985 dlst->
param = (
char *)&dngl_txglomalign;
3988 list_add(&dlst->
list, &bus->
sdiodev->bus_if->dcmd_list);
4003 brcmf_sdbrcm_release(bus);
4014 brcmf_sdbrcm_release(bus);
4043 bus->
timer.expires =