aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
authorFranky Lin <frankyl@broadcom.com>2013-08-10 06:27:28 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-08-15 16:07:55 -0400
commit6bc52319c2c688fdcbb203a4917576ca4cd4d51e (patch)
treedf3ecfe4d68a3b9441ef219c06b9e1956b20aaf6 /drivers/net/wireless/brcm80211/brcmfmac
parentcb7f79682a9289634094e2c3b5180611635332f5 (diff)
brcmfmac: streamline sdio bus header code
Streamlining sdio bus specific header related code as preparation for host tx glomming Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c243
1 files changed, 120 insertions, 123 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 25638753b214..02ab5cdbe29b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -201,13 +201,6 @@ struct rte_console {
201#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */ 201#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */
202#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */ 202#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */
203 203
204/* HW frame tag */
205#define SDPCM_FRAMETAG_LEN 4 /* 2 bytes len, 2 bytes check val */
206
207/* Total length of frame header for dongle protocol */
208#define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN)
209#define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN)
210
211/* 204/*
212 * Software allocation of To SB Mailbox resources 205 * Software allocation of To SB Mailbox resources
213 */ 206 */
@@ -250,38 +243,6 @@ struct rte_console {
250/* Current protocol version */ 243/* Current protocol version */
251#define SDPCM_PROT_VERSION 4 244#define SDPCM_PROT_VERSION 4
252 245
253/* SW frame header */
254#define SDPCM_PACKET_SEQUENCE(p) (((u8 *)p)[0] & 0xff)
255
256#define SDPCM_CHANNEL_MASK 0x00000f00
257#define SDPCM_CHANNEL_SHIFT 8
258#define SDPCM_PACKET_CHANNEL(p) (((u8 *)p)[1] & 0x0f)
259
260#define SDPCM_NEXTLEN_OFFSET 2
261
262/* Data Offset from SOF (HW Tag, SW Tag, Pad) */
263#define SDPCM_DOFFSET_OFFSET 3 /* Data Offset */
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 /* Flow control */
268#define SDPCM_FCMASK_VALUE(p) (((u8 *)p)[SDPCM_FCMASK_OFFSET] & 0xff)
269#define SDPCM_WINDOW_OFFSET 5 /* Credit based fc */
270#define SDPCM_WINDOW_VALUE(p) (((u8 *)p)[SDPCM_WINDOW_OFFSET] & 0xff)
271
272#define SDPCM_SWHEADER_LEN 8 /* SW header is 64 bits */
273
274/* logical channel numbers */
275#define SDPCM_CONTROL_CHANNEL 0 /* Control channel Id */
276#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication Channel Id */
277#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv Channel Id */
278#define SDPCM_GLOM_CHANNEL 3 /* For coalesced packets */
279#define SDPCM_TEST_CHANNEL 15 /* Reserved for test/debug packets */
280
281#define SDPCM_SEQUENCE_WRAP 256 /* wrap-around val for 8bit frame seq */
282
283#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80)
284
285/* 246/*
286 * Shared structure between dongle and the host. 247 * Shared structure between dongle and the host.
287 * The structure contains pointers to trap or assert information. 248 * The structure contains pointers to trap or assert information.
@@ -396,8 +357,8 @@ struct sdpcm_shared_le {
396 __le32 brpt_addr; 357 __le32 brpt_addr;
397}; 358};
398 359
399/* SDIO read frame info */ 360/* dongle SDIO bus specific header info */
400struct brcmf_sdio_read { 361struct brcmf_sdio_hdrinfo {
401 u8 seq_num; 362 u8 seq_num;
402 u8 channel; 363 u8 channel;
403 u16 len; 364 u16 len;
@@ -431,7 +392,7 @@ struct brcmf_sdio {
431 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; 392 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
432 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ 393 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
433 u8 rx_seq; /* Receive sequence number (expected) */ 394 u8 rx_seq; /* Receive sequence number (expected) */
434 struct brcmf_sdio_read cur_read; 395 struct brcmf_sdio_hdrinfo cur_read;
435 /* info of current read frame */ 396 /* info of current read frame */
436 bool rxskip; /* Skip receive (awaiting NAK ACK) */ 397 bool rxskip; /* Skip receive (awaiting NAK ACK) */
437 bool rxpending; /* Data frame pending in dongle */ 398 bool rxpending; /* Data frame pending in dongle */
@@ -1042,18 +1003,64 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
1042 } 1003 }
1043} 1004}
1044 1005
1045static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, 1006/**
1046 struct brcmf_sdio_read *rd, 1007 * brcmfmac sdio bus specific header
1047 enum brcmf_sdio_frmtype type) 1008 * This is the lowest layer header wrapped on the packets transmitted between
1009 * host and WiFi dongle which contains information needed for SDIO core and
1010 * firmware
1011 *
1012 * It consists of 2 parts: hw header and software header
1013 * hardware header (frame tag) - 4 bytes
1014 * Byte 0~1: Frame length
1015 * Byte 2~3: Checksum, bit-wise inverse of frame length
1016 * software header - 8 bytes
1017 * Byte 0: Rx/Tx sequence number
1018 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag
1019 * Byte 2: Length of next data frame, reserved for Tx
1020 * Byte 3: Data offset
1021 * Byte 4: Flow control bits, reserved for Tx
1022 * Byte 5: Maximum Sequence number allowed by firmware for Tx, N/A for Tx packet
1023 * Byte 6~7: Reserved
1024 */
1025#define SDPCM_HWHDR_LEN 4
1026#define SDPCM_SWHDR_LEN 8
1027#define SDPCM_HDRLEN (SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN)
1028#define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN)
1029/* software header */
1030#define SDPCM_SEQ_MASK 0x000000ff
1031#define SDPCM_SEQ_WRAP 256
1032#define SDPCM_CHANNEL_MASK 0x00000f00
1033#define SDPCM_CHANNEL_SHIFT 8
1034#define SDPCM_CONTROL_CHANNEL 0 /* Control */
1035#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication */
1036#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv */
1037#define SDPCM_GLOM_CHANNEL 3 /* Coalesced packets */
1038#define SDPCM_TEST_CHANNEL 15 /* Test/debug packets */
1039#define SDPCM_GLOMDESC(p) (((u8 *)p)[1] & 0x80)
1040#define SDPCM_NEXTLEN_MASK 0x00ff0000
1041#define SDPCM_NEXTLEN_SHIFT 16
1042#define SDPCM_DOFFSET_MASK 0xff000000
1043#define SDPCM_DOFFSET_SHIFT 24
1044#define SDPCM_FCMASK_MASK 0x000000ff
1045#define SDPCM_WINDOW_MASK 0x0000ff00
1046#define SDPCM_WINDOW_SHIFT 8
1047
1048static inline u8 brcmf_sdio_getdatoffset(u8 *swheader)
1049{
1050 u32 hdrvalue;
1051 hdrvalue = *(u32 *)swheader;
1052 return (u8)((hdrvalue & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT);
1053}
1054
1055static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header,
1056 struct brcmf_sdio_hdrinfo *rd,
1057 enum brcmf_sdio_frmtype type)
1048{ 1058{
1049 u16 len, checksum; 1059 u16 len, checksum;
1050 u8 rx_seq, fc, tx_seq_max; 1060 u8 rx_seq, fc, tx_seq_max;
1061 u32 swheader;
1051 1062
1052 /* 1063 /* hw header */
1053 * 4 bytes hardware header (frame tag)
1054 * Byte 0~1: Frame length
1055 * Byte 2~3: Checksum, bit-wise inverse of frame length
1056 */
1057 len = get_unaligned_le16(header); 1064 len = get_unaligned_le16(header);
1058 checksum = get_unaligned_le16(header + sizeof(u16)); 1065 checksum = get_unaligned_le16(header + sizeof(u16));
1059 /* All zero means no more to read */ 1066 /* All zero means no more to read */
@@ -1082,24 +1089,16 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1082 } 1089 }
1083 rd->len = len; 1090 rd->len = len;
1084 1091
1085 /* 1092 /* software header */
1086 * 8 bytes hardware header 1093 header += SDPCM_HWHDR_LEN;
1087 * Byte 0: Rx sequence number 1094 swheader = le32_to_cpu(*(__le32 *)header);
1088 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag 1095 if (type == BRCMF_SDIO_FT_SUPER && SDPCM_GLOMDESC(header)) {
1089 * Byte 2: Length of next data frame
1090 * Byte 3: Data offset
1091 * Byte 4: Flow control bits
1092 * Byte 5: Maximum Sequence number allow for Tx
1093 * Byte 6~7: Reserved
1094 */
1095 if (type == BRCMF_SDIO_FT_SUPER &&
1096 SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) {
1097 brcmf_err("Glom descriptor found in superframe head\n"); 1096 brcmf_err("Glom descriptor found in superframe head\n");
1098 rd->len = 0; 1097 rd->len = 0;
1099 return -EINVAL; 1098 return -EINVAL;
1100 } 1099 }
1101 rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); 1100 rx_seq = (u8)(swheader & SDPCM_SEQ_MASK);
1102 rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); 1101 rd->channel = (swheader & SDPCM_CHANNEL_MASK) >> SDPCM_CHANNEL_SHIFT;
1103 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL && 1102 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL &&
1104 type != BRCMF_SDIO_FT_SUPER) { 1103 type != BRCMF_SDIO_FT_SUPER) {
1105 brcmf_err("HW header length too long\n"); 1104 brcmf_err("HW header length too long\n");
@@ -1119,7 +1118,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1119 rd->len = 0; 1118 rd->len = 0;
1120 return -EINVAL; 1119 return -EINVAL;
1121 } 1120 }
1122 rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); 1121 rd->dat_offset = brcmf_sdio_getdatoffset(header);
1123 if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { 1122 if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) {
1124 brcmf_err("seq %d: bad data offset\n", rx_seq); 1123 brcmf_err("seq %d: bad data offset\n", rx_seq);
1125 bus->sdcnt.rx_badhdr++; 1124 bus->sdcnt.rx_badhdr++;
@@ -1136,14 +1135,15 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1136 /* no need to check the reset for subframe */ 1135 /* no need to check the reset for subframe */
1137 if (type == BRCMF_SDIO_FT_SUB) 1136 if (type == BRCMF_SDIO_FT_SUB)
1138 return 0; 1137 return 0;
1139 rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; 1138 rd->len_nxtfrm = (swheader & SDPCM_NEXTLEN_MASK) >> SDPCM_NEXTLEN_SHIFT;
1140 if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { 1139 if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) {
1141 /* only warm for NON glom packet */ 1140 /* only warm for NON glom packet */
1142 if (rd->channel != SDPCM_GLOM_CHANNEL) 1141 if (rd->channel != SDPCM_GLOM_CHANNEL)
1143 brcmf_err("seq %d: next length error\n", rx_seq); 1142 brcmf_err("seq %d: next length error\n", rx_seq);
1144 rd->len_nxtfrm = 0; 1143 rd->len_nxtfrm = 0;
1145 } 1144 }
1146 fc = SDPCM_FCMASK_VALUE(&header[SDPCM_FRAMETAG_LEN]); 1145 swheader = le32_to_cpu(*(__le32 *)(header + 4));
1146 fc = swheader & SDPCM_FCMASK_MASK;
1147 if (bus->flowcontrol != fc) { 1147 if (bus->flowcontrol != fc) {
1148 if (~bus->flowcontrol & fc) 1148 if (~bus->flowcontrol & fc)
1149 bus->sdcnt.fc_xoff++; 1149 bus->sdcnt.fc_xoff++;
@@ -1152,7 +1152,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1152 bus->sdcnt.fc_rcvd++; 1152 bus->sdcnt.fc_rcvd++;
1153 bus->flowcontrol = fc; 1153 bus->flowcontrol = fc;
1154 } 1154 }
1155 tx_seq_max = SDPCM_WINDOW_VALUE(&header[SDPCM_FRAMETAG_LEN]); 1155 tx_seq_max = (swheader & SDPCM_WINDOW_MASK) >> SDPCM_WINDOW_SHIFT;
1156 if ((u8)(tx_seq_max - bus->tx_seq) > 0x40) { 1156 if ((u8)(tx_seq_max - bus->tx_seq) > 0x40) {
1157 brcmf_err("seq %d: max tx seq number error\n", rx_seq); 1157 brcmf_err("seq %d: max tx seq number error\n", rx_seq);
1158 tx_seq_max = bus->tx_seq + 2; 1158 tx_seq_max = bus->tx_seq + 2;
@@ -1162,6 +1162,28 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1162 return 0; 1162 return 0;
1163} 1163}
1164 1164
1165static inline void brcmf_sdio_update_hwhdr(u8 *header, u16 frm_length)
1166{
1167 *(__le16 *)header = cpu_to_le16(frm_length);
1168 *(((__le16 *)header) + 1) = cpu_to_le16(~frm_length);
1169}
1170
1171static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header,
1172 struct brcmf_sdio_hdrinfo *hd_info)
1173{
1174 u32 sw_header;
1175
1176 brcmf_sdio_update_hwhdr(header, hd_info->len);
1177
1178 sw_header = bus->tx_seq;
1179 sw_header |= (hd_info->channel << SDPCM_CHANNEL_SHIFT) &
1180 SDPCM_CHANNEL_MASK;
1181 sw_header |= (hd_info->dat_offset << SDPCM_DOFFSET_SHIFT) &
1182 SDPCM_DOFFSET_MASK;
1183 *(((__le32 *)header) + 1) = cpu_to_le32(sw_header);
1184 *(((__le32 *)header) + 2) = 0;
1185}
1186
1165static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) 1187static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1166{ 1188{
1167 u16 dlen, totlen; 1189 u16 dlen, totlen;
@@ -1173,7 +1195,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1173 int errcode; 1195 int errcode;
1174 u8 doff, sfdoff; 1196 u8 doff, sfdoff;
1175 1197
1176 struct brcmf_sdio_read rd_new; 1198 struct brcmf_sdio_hdrinfo rd_new;
1177 1199
1178 /* If packets, issue read(s) and send up packet chain */ 1200 /* If packets, issue read(s) and send up packet chain */
1179 /* Return sequence numbers consumed? */ 1201 /* Return sequence numbers consumed? */
@@ -1309,8 +1331,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1309 rd_new.seq_num = rxseq; 1331 rd_new.seq_num = rxseq;
1310 rd_new.len = dlen; 1332 rd_new.len = dlen;
1311 sdio_claim_host(bus->sdiodev->func[1]); 1333 sdio_claim_host(bus->sdiodev->func[1]);
1312 errcode = brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, 1334 errcode = brcmf_sdio_hdparse(bus, pfirst->data, &rd_new,
1313 BRCMF_SDIO_FT_SUPER); 1335 BRCMF_SDIO_FT_SUPER);
1314 sdio_release_host(bus->sdiodev->func[1]); 1336 sdio_release_host(bus->sdiodev->func[1]);
1315 bus->cur_read.len = rd_new.len_nxtfrm << 4; 1337 bus->cur_read.len = rd_new.len_nxtfrm << 4;
1316 1338
@@ -1328,8 +1350,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1328 rd_new.len = pnext->len; 1350 rd_new.len = pnext->len;
1329 rd_new.seq_num = rxseq++; 1351 rd_new.seq_num = rxseq++;
1330 sdio_claim_host(bus->sdiodev->func[1]); 1352 sdio_claim_host(bus->sdiodev->func[1]);
1331 errcode = brcmf_sdio_hdparser(bus, pnext->data, &rd_new, 1353 errcode = brcmf_sdio_hdparse(bus, pnext->data, &rd_new,
1332 BRCMF_SDIO_FT_SUB); 1354 BRCMF_SDIO_FT_SUB);
1333 sdio_release_host(bus->sdiodev->func[1]); 1355 sdio_release_host(bus->sdiodev->func[1]);
1334 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), 1356 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
1335 pnext->data, 32, "subframe:\n"); 1357 pnext->data, 32, "subframe:\n");
@@ -1361,7 +1383,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1361 skb_queue_walk_safe(&bus->glom, pfirst, pnext) { 1383 skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
1362 dptr = (u8 *) (pfirst->data); 1384 dptr = (u8 *) (pfirst->data);
1363 sublen = get_unaligned_le16(dptr); 1385 sublen = get_unaligned_le16(dptr);
1364 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); 1386 doff = brcmf_sdio_getdatoffset(&dptr[SDPCM_HWHDR_LEN]);
1365 1387
1366 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), 1388 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
1367 dptr, pfirst->len, 1389 dptr, pfirst->len,
@@ -1539,7 +1561,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1539 uint rxleft = 0; /* Remaining number of frames allowed */ 1561 uint rxleft = 0; /* Remaining number of frames allowed */
1540 int ret; /* Return code from calls */ 1562 int ret; /* Return code from calls */
1541 uint rxcount = 0; /* Total frames read */ 1563 uint rxcount = 0; /* Total frames read */
1542 struct brcmf_sdio_read *rd = &bus->cur_read, rd_new; 1564 struct brcmf_sdio_hdrinfo *rd = &bus->cur_read, rd_new;
1543 u8 head_read = 0; 1565 u8 head_read = 0;
1544 1566
1545 brcmf_dbg(TRACE, "Enter\n"); 1567 brcmf_dbg(TRACE, "Enter\n");
@@ -1587,8 +1609,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1587 bus->rxhdr, SDPCM_HDRLEN, 1609 bus->rxhdr, SDPCM_HDRLEN,
1588 "RxHdr:\n"); 1610 "RxHdr:\n");
1589 1611
1590 if (brcmf_sdio_hdparser(bus, bus->rxhdr, rd, 1612 if (brcmf_sdio_hdparse(bus, bus->rxhdr, rd,
1591 BRCMF_SDIO_FT_NORMAL)) { 1613 BRCMF_SDIO_FT_NORMAL)) {
1592 sdio_release_host(bus->sdiodev->func[1]); 1614 sdio_release_host(bus->sdiodev->func[1]);
1593 if (!bus->rxpending) 1615 if (!bus->rxpending)
1594 break; 1616 break;
@@ -1652,8 +1674,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1652 memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); 1674 memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
1653 rd_new.seq_num = rd->seq_num; 1675 rd_new.seq_num = rd->seq_num;
1654 sdio_claim_host(bus->sdiodev->func[1]); 1676 sdio_claim_host(bus->sdiodev->func[1]);
1655 if (brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, 1677 if (brcmf_sdio_hdparse(bus, bus->rxhdr, &rd_new,
1656 BRCMF_SDIO_FT_NORMAL)) { 1678 BRCMF_SDIO_FT_NORMAL)) {
1657 rd->len = 0; 1679 rd->len = 0;
1658 brcmu_pkt_buf_free_skb(pkt); 1680 brcmu_pkt_buf_free_skb(pkt);
1659 } 1681 }
@@ -1697,7 +1719,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1697 1719
1698 /* Save superframe descriptor and allocate packet frame */ 1720 /* Save superframe descriptor and allocate packet frame */
1699 if (rd->channel == SDPCM_GLOM_CHANNEL) { 1721 if (rd->channel == SDPCM_GLOM_CHANNEL) {
1700 if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { 1722 if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_HWHDR_LEN])) {
1701 brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", 1723 brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
1702 rd->len); 1724 rd->len);
1703 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), 1725 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
@@ -1783,13 +1805,12 @@ static int
1783brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, 1805brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
1784 uint chan) 1806 uint chan)
1785{ 1807{
1786 u16 head_pad, tail_pad, tail_chop, pkt_len; 1808 u16 head_pad, tail_pad, tail_chop, head_align, sg_align;
1787 u16 head_align, sg_align;
1788 u32 sw_header;
1789 int ntail; 1809 int ntail;
1790 struct sk_buff *pkt_next, *pkt_new; 1810 struct sk_buff *pkt_next, *pkt_new;
1791 u8 *dat_buf; 1811 u8 *dat_buf;
1792 unsigned blksize = bus->sdiodev->func[SDIO_FUNC_2]->cur_blksize; 1812 unsigned blksize = bus->sdiodev->func[SDIO_FUNC_2]->cur_blksize;
1813 struct brcmf_sdio_hdrinfo hd_info = {0};
1793 1814
1794 /* SDIO ADMA requires at least 32 bit alignment */ 1815 /* SDIO ADMA requires at least 32 bit alignment */
1795 head_align = 4; 1816 head_align = 4;
@@ -1848,34 +1869,18 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
1848 } 1869 }
1849 1870
1850 /* Now prep the header */ 1871 /* Now prep the header */
1851 /* 4 bytes hardware header (frame tag)
1852 * Byte 0~1: Frame length
1853 * Byte 2~3: Checksum, bit-wise inverse of frame length
1854 */
1855 if (pkt_new) 1872 if (pkt_new)
1856 pkt_len = pkt_next->len + tail_chop; 1873 hd_info.len = pkt_next->len + tail_chop;
1857 else 1874 else
1858 pkt_len = pkt_next->len - tail_pad; 1875 hd_info.len = pkt_next->len - tail_pad;
1859 *(__le16 *)dat_buf = cpu_to_le16(pkt_len); 1876 hd_info.channel = chan;
1860 *(((__le16 *)dat_buf) + 1) = cpu_to_le16(~pkt_len); 1877 hd_info.dat_offset = head_pad + SDPCM_HDRLEN;
1861 /* 8 bytes software header 1878 brcmf_sdio_hdpack(bus, dat_buf, &hd_info);
1862 * Byte 0: Tx sequence number
1863 * Byte 1: 4 MSB Channel number
1864 * Byte 2: Reserved
1865 * Byte 3: Data offset
1866 * Byte 4~7: Reserved
1867 */
1868 sw_header = bus->tx_seq;
1869 sw_header |= ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK);
1870 sw_header |= ((head_pad + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) &
1871 SDPCM_DOFFSET_MASK;
1872 *(((__le32 *)dat_buf) + 1) = cpu_to_le32(sw_header);
1873 *(((__le32 *)dat_buf) + 2) = 0;
1874 1879
1875 if (BRCMF_BYTES_ON() && 1880 if (BRCMF_BYTES_ON() &&
1876 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || 1881 ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) ||
1877 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) 1882 (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)))
1878 brcmf_dbg_hex_dump(true, pkt_next, pkt_len, "Tx Frame:\n"); 1883 brcmf_dbg_hex_dump(true, pkt_next, hd_info.len, "Tx Frame:\n");
1879 else if (BRCMF_HDRS_ON()) 1884 else if (BRCMF_HDRS_ON())
1880 brcmf_dbg_hex_dump(true, pkt_next, head_pad + SDPCM_HDRLEN, 1885 brcmf_dbg_hex_dump(true, pkt_next, head_pad + SDPCM_HDRLEN,
1881 "Tx Header:\n"); 1886 "Tx Header:\n");
@@ -1913,7 +1918,7 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
1913 __skb_unlink(pkt_next, pktq); 1918 __skb_unlink(pkt_next, pktq);
1914 brcmu_pkt_buf_free_skb(pkt_next); 1919 brcmu_pkt_buf_free_skb(pkt_next);
1915 } else { 1920 } else {
1916 hdr = pkt_next->data + SDPCM_FRAMETAG_LEN; 1921 hdr = pkt_next->data + SDPCM_HWHDR_LEN;
1917 dat_offset = le32_to_cpu(*(__le32 *)hdr); 1922 dat_offset = le32_to_cpu(*(__le32 *)hdr);
1918 dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >> 1923 dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >>
1919 SDPCM_DOFFSET_SHIFT; 1924 SDPCM_DOFFSET_SHIFT;
@@ -1969,7 +1974,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
1969 } 1974 }
1970 sdio_release_host(bus->sdiodev->func[1]); 1975 sdio_release_host(bus->sdiodev->func[1]);
1971 if (ret == 0) 1976 if (ret == 0)
1972 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 1977 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
1973 1978
1974done: 1979done:
1975 brcmf_sdio_txpkt_postp(bus, &localq); 1980 brcmf_sdio_txpkt_postp(bus, &localq);
@@ -2325,7 +2330,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2325 } 2330 }
2326 2331
2327 } else { 2332 } else {
2328 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 2333 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2329 } 2334 }
2330 sdio_release_host(bus->sdiodev->func[1]); 2335 sdio_release_host(bus->sdiodev->func[1]);
2331 bus->ctrl_frame_stat = false; 2336 bus->ctrl_frame_stat = false;
@@ -2540,7 +2545,7 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len)
2540 return ret; 2545 return ret;
2541 } 2546 }
2542 2547
2543 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 2548 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQ_WRAP;
2544 2549
2545 return ret; 2550 return ret;
2546} 2551}
@@ -2550,13 +2555,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2550{ 2555{
2551 u8 *frame; 2556 u8 *frame;
2552 u16 len; 2557 u16 len;
2553 u32 swheader;
2554 uint retries = 0; 2558 uint retries = 0;
2555 u8 doff = 0; 2559 u8 doff = 0;
2556 int ret = -1; 2560 int ret = -1;
2557 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2561 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2558 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2562 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2559 struct brcmf_sdio *bus = sdiodev->bus; 2563 struct brcmf_sdio *bus = sdiodev->bus;
2564 struct brcmf_sdio_hdrinfo hd_info = {0};
2560 2565
2561 brcmf_dbg(TRACE, "Enter\n"); 2566 brcmf_dbg(TRACE, "Enter\n");
2562 2567
@@ -2595,18 +2600,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2595 brcmf_sdbrcm_bus_sleep(bus, false, false); 2600 brcmf_sdbrcm_bus_sleep(bus, false, false);
2596 sdio_release_host(bus->sdiodev->func[1]); 2601 sdio_release_host(bus->sdiodev->func[1]);
2597 2602
2598 /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ 2603 hd_info.len = (u16)msglen;
2599 *(__le16 *) frame = cpu_to_le16((u16) msglen); 2604 hd_info.channel = SDPCM_CONTROL_CHANNEL;
2600 *(((__le16 *) frame) + 1) = cpu_to_le16(~msglen); 2605 hd_info.dat_offset = doff;
2601 2606 brcmf_sdio_hdpack(bus, frame, &hd_info);
2602 /* Software tag: channel, sequence number, data offset */
2603 swheader =
2604 ((SDPCM_CONTROL_CHANNEL << SDPCM_CHANNEL_SHIFT) &
2605 SDPCM_CHANNEL_MASK)
2606 | bus->tx_seq | ((doff << SDPCM_DOFFSET_SHIFT) &
2607 SDPCM_DOFFSET_MASK);
2608 put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN);
2609 put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader));
2610 2607
2611 if (!data_ok(bus)) { 2608 if (!data_ok(bus)) {
2612 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", 2609 brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
@@ -3856,7 +3853,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3856 bus->txbound = BRCMF_TXBOUND; 3853 bus->txbound = BRCMF_TXBOUND;
3857 bus->rxbound = BRCMF_RXBOUND; 3854 bus->rxbound = BRCMF_RXBOUND;
3858 bus->txminmax = BRCMF_TXMINMAX; 3855 bus->txminmax = BRCMF_TXMINMAX;
3859 bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; 3856 bus->tx_seq = SDPCM_SEQ_WRAP - 1;
3860 3857
3861 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); 3858 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
3862 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); 3859 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");