diff options
author | Franky Lin <frankyl@broadcom.com> | 2013-08-10 06:27:26 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-08-15 16:07:55 -0400 |
commit | b05e92545d9582be15699e4a33d0f93ac00b37dd (patch) | |
tree | 7c0da83047da08922ac2917cd1a409cdd0edbf33 | |
parent | 89c2f382fff4ec8adf04264925e07e951d0552ce (diff) |
brcmfmac: abstract tx packet processing functions
Abstract brcmf_sdio_txpkt_prep and brcmf_sdio_txpkt_postp as a preparation
of chained tx packets for host side tx glomming.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@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>
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 16 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 237 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | 2 | ||||
-rw-r--r-- | include/linux/platform_data/brcmfmac-sdio.h | 6 |
4 files changed, 183 insertions, 78 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index e3f3c48f86d4..e13b1a65c65f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -592,6 +592,7 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
592 | uint flags, u8 *buf, uint nbytes) | 592 | uint flags, u8 *buf, uint nbytes) |
593 | { | 593 | { |
594 | struct sk_buff *mypkt; | 594 | struct sk_buff *mypkt; |
595 | struct sk_buff_head pktq; | ||
595 | int err; | 596 | int err; |
596 | 597 | ||
597 | mypkt = brcmu_pkt_buf_get_skb(nbytes); | 598 | mypkt = brcmu_pkt_buf_get_skb(nbytes); |
@@ -602,7 +603,10 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
602 | } | 603 | } |
603 | 604 | ||
604 | memcpy(mypkt->data, buf, nbytes); | 605 | memcpy(mypkt->data, buf, nbytes); |
605 | err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, mypkt); | 606 | __skb_queue_head_init(&pktq); |
607 | __skb_queue_tail(&pktq, mypkt); | ||
608 | err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, &pktq); | ||
609 | __skb_dequeue_tail(&pktq); | ||
606 | 610 | ||
607 | brcmu_pkt_buf_free_skb(mypkt); | 611 | brcmu_pkt_buf_free_skb(mypkt); |
608 | return err; | 612 | return err; |
@@ -611,22 +615,18 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
611 | 615 | ||
612 | int | 616 | int |
613 | brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | 617 | brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, |
614 | uint flags, struct sk_buff *pkt) | 618 | uint flags, struct sk_buff_head *pktq) |
615 | { | 619 | { |
616 | uint width; | 620 | uint width; |
617 | int err = 0; | 621 | int err = 0; |
618 | struct sk_buff_head pkt_list; | ||
619 | 622 | ||
620 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", | 623 | brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", |
621 | fn, addr, pkt->len); | 624 | fn, addr, pktq->qlen); |
622 | 625 | ||
623 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 626 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
624 | brcmf_sdio_addrprep(sdiodev, width, &addr); | 627 | brcmf_sdio_addrprep(sdiodev, width, &addr); |
625 | 628 | ||
626 | skb_queue_head_init(&pkt_list); | 629 | err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, pktq); |
627 | skb_queue_tail(&pkt_list, pkt); | ||
628 | err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list); | ||
629 | skb_dequeue_tail(&pkt_list); | ||
630 | 630 | ||
631 | return err; | 631 | return err; |
632 | } | 632 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index db31312eba6a..aa4cacaf8b03 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -510,7 +510,6 @@ struct brcmf_sdio { | |||
510 | 510 | ||
511 | #ifdef DEBUG | 511 | #ifdef DEBUG |
512 | static int qcount[NUMPRIO]; | 512 | static int qcount[NUMPRIO]; |
513 | static int tx_packets[NUMPRIO]; | ||
514 | #endif /* DEBUG */ | 513 | #endif /* DEBUG */ |
515 | 514 | ||
516 | #define DEFAULT_SDIO_DRIVE_STRENGTH 6 /* in milliamps */ | 515 | #define DEFAULT_SDIO_DRIVE_STRENGTH 6 /* in milliamps */ |
@@ -1759,85 +1758,185 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) | |||
1759 | return; | 1758 | return; |
1760 | } | 1759 | } |
1761 | 1760 | ||
1761 | /* flag marking a dummy skb added for DMA alignment requirement */ | ||
1762 | #define DUMMY_SKB_FLAG 0x10000 | ||
1763 | /* bit mask of data length chopped from the previous packet */ | ||
1764 | #define DUMMY_SKB_CHOP_LEN_MASK 0xffff | ||
1765 | /** | ||
1766 | * brcmf_sdio_txpkt_prep - packet preparation for transmit | ||
1767 | * @bus: brcmf_sdio structure pointer | ||
1768 | * @pktq: packet list pointer | ||
1769 | * @chan: virtual channel to transmit the packet | ||
1770 | * | ||
1771 | * Processes to be applied to the packet | ||
1772 | * - Align data buffer pointer | ||
1773 | * - Align data buffer length | ||
1774 | * - Prepare header | ||
1775 | * Return: negative value if there is error | ||
1776 | */ | ||
1777 | static int | ||
1778 | brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, | ||
1779 | uint chan) | ||
1780 | { | ||
1781 | u16 head_pad, tail_pad, tail_chop, pkt_len; | ||
1782 | u16 head_align, sg_align; | ||
1783 | u32 sw_header; | ||
1784 | int ntail; | ||
1785 | struct sk_buff *pkt_next, *pkt_new; | ||
1786 | u8 *dat_buf; | ||
1787 | unsigned blksize = bus->sdiodev->func[SDIO_FUNC_2]->cur_blksize; | ||
1788 | |||
1789 | /* SDIO ADMA requires at least 32 bit alignment */ | ||
1790 | head_align = 4; | ||
1791 | sg_align = 4; | ||
1792 | if (bus->sdiodev->pdata) { | ||
1793 | head_align = bus->sdiodev->pdata->sd_head_align > 4 ? | ||
1794 | bus->sdiodev->pdata->sd_head_align : 4; | ||
1795 | sg_align = bus->sdiodev->pdata->sd_sgentry_align > 4 ? | ||
1796 | bus->sdiodev->pdata->sd_sgentry_align : 4; | ||
1797 | } | ||
1798 | /* sg entry alignment should be a divisor of block size */ | ||
1799 | WARN_ON(blksize % sg_align); | ||
1800 | |||
1801 | pkt_next = pktq->next; | ||
1802 | dat_buf = (u8 *)(pkt_next->data); | ||
1803 | |||
1804 | /* Check head padding */ | ||
1805 | head_pad = ((unsigned long)dat_buf % head_align); | ||
1806 | if (head_pad) { | ||
1807 | if (skb_headroom(pkt_next) < head_pad) { | ||
1808 | bus->sdiodev->bus_if->tx_realloc++; | ||
1809 | head_pad = 0; | ||
1810 | if (skb_cow(pkt_next, head_pad)) | ||
1811 | return -ENOMEM; | ||
1812 | } | ||
1813 | skb_push(pkt_next, head_pad); | ||
1814 | dat_buf = (u8 *)(pkt_next->data); | ||
1815 | memset(dat_buf, 0, head_pad + SDPCM_HDRLEN); | ||
1816 | } | ||
1817 | |||
1818 | /* Check tail padding */ | ||
1819 | pkt_new = NULL; | ||
1820 | tail_chop = pkt_next->len % sg_align; | ||
1821 | tail_pad = sg_align - tail_chop; | ||
1822 | tail_pad += blksize - (pkt_next->len + tail_pad) % blksize; | ||
1823 | if (skb_tailroom(pkt_next) < tail_pad && pkt_next->len > blksize) { | ||
1824 | pkt_new = brcmu_pkt_buf_get_skb(tail_pad + tail_chop); | ||
1825 | if (pkt_new == NULL) | ||
1826 | return -ENOMEM; | ||
1827 | memcpy(pkt_new->data, | ||
1828 | pkt_next->data + pkt_next->len - tail_chop, | ||
1829 | tail_chop); | ||
1830 | *(u32 *)(pkt_new->cb) = DUMMY_SKB_FLAG + tail_chop; | ||
1831 | skb_trim(pkt_next, pkt_next->len - tail_chop); | ||
1832 | __skb_queue_after(pktq, pkt_next, pkt_new); | ||
1833 | } else { | ||
1834 | ntail = pkt_next->data_len + tail_pad - | ||
1835 | (pkt_next->end - pkt_next->tail); | ||
1836 | if (skb_cloned(pkt_next) || ntail > 0) | ||
1837 | if (pskb_expand_head(pkt_next, 0, ntail, GFP_ATOMIC)) | ||
1838 | return -ENOMEM; | ||
1839 | if (skb_linearize(pkt_next)) | ||
1840 | return -ENOMEM; | ||
1841 | dat_buf = (u8 *)(pkt_next->data); | ||
1842 | __skb_put(pkt_next, tail_pad); | ||
1843 | } | ||
1844 | |||
1845 | /* Now prep the header */ | ||
1846 | /* 4 bytes hardware header (frame tag) | ||
1847 | * Byte 0~1: Frame length | ||
1848 | * Byte 2~3: Checksum, bit-wise inverse of frame length | ||
1849 | */ | ||
1850 | if (pkt_new) | ||
1851 | pkt_len = pkt_next->len + tail_chop; | ||
1852 | else | ||
1853 | pkt_len = pkt_next->len - tail_pad; | ||
1854 | *(__le16 *)dat_buf = cpu_to_le16(pkt_len); | ||
1855 | *(((__le16 *)dat_buf) + 1) = cpu_to_le16(~pkt_len); | ||
1856 | /* 8 bytes software header | ||
1857 | * Byte 0: Tx sequence number | ||
1858 | * Byte 1: 4 MSB Channel number | ||
1859 | * Byte 2: Reserved | ||
1860 | * Byte 3: Data offset | ||
1861 | * Byte 4~7: Reserved | ||
1862 | */ | ||
1863 | sw_header = bus->tx_seq; | ||
1864 | sw_header |= ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK); | ||
1865 | sw_header |= ((head_pad + SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & | ||
1866 | SDPCM_DOFFSET_MASK; | ||
1867 | *(((__le32 *)dat_buf) + 1) = cpu_to_le32(sw_header); | ||
1868 | *(((__le32 *)dat_buf) + 2) = 0; | ||
1869 | |||
1870 | if (BRCMF_BYTES_ON() && | ||
1871 | ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || | ||
1872 | (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL))) | ||
1873 | brcmf_dbg_hex_dump(true, pkt_next, pkt_len, "Tx Frame:\n"); | ||
1874 | else if (BRCMF_HDRS_ON()) | ||
1875 | brcmf_dbg_hex_dump(true, pkt_next, head_pad + SDPCM_HDRLEN, | ||
1876 | "Tx Header:\n"); | ||
1877 | |||
1878 | return 0; | ||
1879 | } | ||
1880 | |||
1881 | /** | ||
1882 | * brcmf_sdio_txpkt_postp - packet post processing for transmit | ||
1883 | * @bus: brcmf_sdio structure pointer | ||
1884 | * @pktq: packet list pointer | ||
1885 | * | ||
1886 | * Processes to be applied to the packet | ||
1887 | * - Remove head padding | ||
1888 | * - Remove tail padding | ||
1889 | */ | ||
1890 | static void | ||
1891 | brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq) | ||
1892 | { | ||
1893 | u8 *hdr; | ||
1894 | u32 dat_offset; | ||
1895 | u32 dummy_flags, chop_len; | ||
1896 | struct sk_buff *pkt_next, *tmp, *pkt_prev; | ||
1897 | |||
1898 | skb_queue_walk_safe(pktq, pkt_next, tmp) { | ||
1899 | dummy_flags = *(u32 *)(pkt_next->cb); | ||
1900 | if (dummy_flags & DUMMY_SKB_FLAG) { | ||
1901 | chop_len = dummy_flags & DUMMY_SKB_CHOP_LEN_MASK; | ||
1902 | if (chop_len) { | ||
1903 | pkt_prev = pkt_next->prev; | ||
1904 | memcpy(pkt_prev->data + pkt_prev->len, | ||
1905 | pkt_next->data, chop_len); | ||
1906 | skb_put(pkt_prev, chop_len); | ||
1907 | } | ||
1908 | __skb_unlink(pkt_next, pktq); | ||
1909 | brcmu_pkt_buf_free_skb(pkt_next); | ||
1910 | } else { | ||
1911 | hdr = pkt_next->data + SDPCM_FRAMETAG_LEN; | ||
1912 | dat_offset = le32_to_cpu(*(__le32 *)hdr); | ||
1913 | dat_offset = (dat_offset & SDPCM_DOFFSET_MASK) >> | ||
1914 | SDPCM_DOFFSET_SHIFT; | ||
1915 | skb_pull(pkt_next, dat_offset); | ||
1916 | } | ||
1917 | } | ||
1918 | } | ||
1919 | |||
1762 | /* Writes a HW/SW header into the packet and sends it. */ | 1920 | /* Writes a HW/SW header into the packet and sends it. */ |
1763 | /* Assumes: (a) header space already there, (b) caller holds lock */ | 1921 | /* Assumes: (a) header space already there, (b) caller holds lock */ |
1764 | static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, | 1922 | static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, |
1765 | uint chan) | 1923 | uint chan) |
1766 | { | 1924 | { |
1767 | int ret; | 1925 | int ret; |
1768 | u8 *frame; | ||
1769 | u16 len, pad = 0; | ||
1770 | u32 swheader; | ||
1771 | int i; | 1926 | int i; |
1927 | struct sk_buff_head localq; | ||
1772 | 1928 | ||
1773 | brcmf_dbg(TRACE, "Enter\n"); | 1929 | brcmf_dbg(TRACE, "Enter\n"); |
1774 | 1930 | ||
1775 | frame = (u8 *) (pkt->data); | 1931 | __skb_queue_head_init(&localq); |
1776 | 1932 | __skb_queue_tail(&localq, pkt); | |
1777 | /* Add alignment padding, allocate new packet if needed */ | 1933 | ret = brcmf_sdio_txpkt_prep(bus, &localq, chan); |
1778 | pad = ((unsigned long)frame % BRCMF_SDALIGN); | 1934 | if (ret) |
1779 | if (pad) { | 1935 | goto done; |
1780 | if (skb_headroom(pkt) < pad) { | ||
1781 | brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n", | ||
1782 | skb_headroom(pkt), pad); | ||
1783 | bus->sdiodev->bus_if->tx_realloc++; | ||
1784 | ret = skb_cow(pkt, BRCMF_SDALIGN); | ||
1785 | if (ret) | ||
1786 | goto done; | ||
1787 | pad = ((unsigned long)frame % BRCMF_SDALIGN); | ||
1788 | } | ||
1789 | skb_push(pkt, pad); | ||
1790 | frame = (u8 *) (pkt->data); | ||
1791 | memset(frame, 0, pad + SDPCM_HDRLEN); | ||
1792 | } | ||
1793 | /* precondition: pad < BRCMF_SDALIGN */ | ||
1794 | |||
1795 | /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ | ||
1796 | len = (u16) (pkt->len); | ||
1797 | *(__le16 *) frame = cpu_to_le16(len); | ||
1798 | *(((__le16 *) frame) + 1) = cpu_to_le16(~len); | ||
1799 | |||
1800 | /* Software tag: channel, sequence number, data offset */ | ||
1801 | swheader = | ||
1802 | ((chan << SDPCM_CHANNEL_SHIFT) & SDPCM_CHANNEL_MASK) | bus->tx_seq | | ||
1803 | (((pad + | ||
1804 | SDPCM_HDRLEN) << SDPCM_DOFFSET_SHIFT) & SDPCM_DOFFSET_MASK); | ||
1805 | |||
1806 | *(((__le32 *) frame) + 1) = cpu_to_le32(swheader); | ||
1807 | *(((__le32 *) frame) + 2) = 0; | ||
1808 | |||
1809 | #ifdef DEBUG | ||
1810 | tx_packets[pkt->priority]++; | ||
1811 | #endif | ||
1812 | |||
1813 | brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && | ||
1814 | ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || | ||
1815 | (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)), | ||
1816 | frame, len, "Tx Frame:\n"); | ||
1817 | brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && | ||
1818 | ((BRCMF_CTL_ON() && | ||
1819 | chan == SDPCM_CONTROL_CHANNEL) || | ||
1820 | (BRCMF_DATA_ON() && | ||
1821 | chan != SDPCM_CONTROL_CHANNEL))) && | ||
1822 | BRCMF_HDRS_ON(), | ||
1823 | frame, min_t(u16, len, 16), "TxHdr:\n"); | ||
1824 | |||
1825 | /* Raise len to next SDIO block to eliminate tail command */ | ||
1826 | if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { | ||
1827 | u16 pad = bus->blocksize - (len % bus->blocksize); | ||
1828 | if ((pad <= bus->roundup) && (pad < bus->blocksize)) | ||
1829 | len += pad; | ||
1830 | } else if (len % BRCMF_SDALIGN) { | ||
1831 | len += BRCMF_SDALIGN - (len % BRCMF_SDALIGN); | ||
1832 | } | ||
1833 | |||
1834 | /* Some controllers have trouble with odd bytes -- round to even */ | ||
1835 | if (len & (ALIGNMENT - 1)) | ||
1836 | len = roundup(len, ALIGNMENT); | ||
1837 | 1936 | ||
1838 | sdio_claim_host(bus->sdiodev->func[1]); | 1937 | sdio_claim_host(bus->sdiodev->func[1]); |
1839 | ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, | 1938 | ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, |
1840 | SDIO_FUNC_2, F2SYNC, pkt); | 1939 | SDIO_FUNC_2, F2SYNC, &localq); |
1841 | bus->sdcnt.f2txdata++; | 1940 | bus->sdcnt.f2txdata++; |
1842 | 1941 | ||
1843 | if (ret < 0) { | 1942 | if (ret < 0) { |
@@ -1868,8 +1967,8 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, | |||
1868 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; | 1967 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; |
1869 | 1968 | ||
1870 | done: | 1969 | done: |
1871 | /* restore pkt buffer pointer before calling tx complete routine */ | 1970 | brcmf_sdio_txpkt_postp(bus, &localq); |
1872 | skb_pull(pkt, SDPCM_HDRLEN + pad); | 1971 | __skb_dequeue_tail(&localq); |
1873 | brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0); | 1972 | brcmf_txcomplete(bus->sdiodev->dev, pkt, ret == 0); |
1874 | return ret; | 1973 | return ret; |
1875 | } | 1974 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index 09786a539950..2b5407f002e5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | |||
@@ -208,7 +208,7 @@ extern int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
208 | */ | 208 | */ |
209 | extern int | 209 | extern int |
210 | brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | 210 | brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, |
211 | uint flags, struct sk_buff *pkt); | 211 | uint flags, struct sk_buff_head *pktq); |
212 | extern int | 212 | extern int |
213 | brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | 213 | brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, |
214 | uint flags, u8 *buf, uint nbytes); | 214 | uint flags, u8 *buf, uint nbytes); |
diff --git a/include/linux/platform_data/brcmfmac-sdio.h b/include/linux/platform_data/brcmfmac-sdio.h index b7174998c24a..e75dcbf2b230 100644 --- a/include/linux/platform_data/brcmfmac-sdio.h +++ b/include/linux/platform_data/brcmfmac-sdio.h | |||
@@ -94,6 +94,10 @@ void __init brcmfmac_init_pdata(void) | |||
94 | * Set this to true if the SDIO host controller has higher align requirement | 94 | * Set this to true if the SDIO host controller has higher align requirement |
95 | * than 32 bytes for each scatterlist item. | 95 | * than 32 bytes for each scatterlist item. |
96 | * | 96 | * |
97 | * sd_head_align: alignment requirement for start of data buffer | ||
98 | * | ||
99 | * sd_sgentry_align: length alignment requirement for each sg entry | ||
100 | * | ||
97 | * power_on: This function is called by the brcmfmac when the module gets | 101 | * power_on: This function is called by the brcmfmac when the module gets |
98 | * loaded. This can be particularly useful for low power devices. The platform | 102 | * loaded. This can be particularly useful for low power devices. The platform |
99 | * spcific routine may for example decide to power up the complete device. | 103 | * spcific routine may for example decide to power up the complete device. |
@@ -121,6 +125,8 @@ struct brcmfmac_sdio_platform_data { | |||
121 | unsigned int oob_irq_nr; | 125 | unsigned int oob_irq_nr; |
122 | unsigned long oob_irq_flags; | 126 | unsigned long oob_irq_flags; |
123 | bool broken_sg_support; | 127 | bool broken_sg_support; |
128 | unsigned short sd_head_align; | ||
129 | unsigned short sd_sgentry_align; | ||
124 | void (*power_on)(void); | 130 | void (*power_on)(void); |
125 | void (*power_off)(void); | 131 | void (*power_off)(void); |
126 | void (*reset)(void); | 132 | void (*reset)(void); |