aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorBing Zhao <bzhao@marvell.com>2009-05-19 22:48:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-22 14:06:00 -0400
commitb136a1414c94b4bda1057b4ffde26253d2527628 (patch)
tree0a534b4665d2b9478f2372473587b1d881e783e7 /drivers/net/wireless/libertas
parente70a5ac5d27166cfe5bfbe8f63017af3b09d72ce (diff)
libertas: get SD8688 rx length with one CMD52
Usually, the 16-bit rx length is read from scratch pad registers with two CMD52 transactions: SD8385: IF_SDIO_SCRATCH_OLD (0x80fe/0x80ff) SD8686/SD8688: IF_SDIO_SCRATCH (0x34/0x35) Alternatively, SD8688 firmware offers an enhanced method for driver to read an 8-bit rx length (in units) with a single CMD52: IF_SDIO_RX_UNIT 0x43 is read one time after firmware is ready. IF_SDIO_RX_LEN 0x42 is read every time when rx interrupt is received. Signed-off-by: Bing Zhao <bzhao@marvell.com> Acked-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/libertas')
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c57
-rw-r--r--drivers/net/wireless/libertas/if_sdio.h3
2 files changed, 58 insertions, 2 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 69d7fd31319a..e998c123e0c5 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -107,6 +107,8 @@ struct if_sdio_card {
107 107
108 struct workqueue_struct *workqueue; 108 struct workqueue_struct *workqueue;
109 struct work_struct packet_worker; 109 struct work_struct packet_worker;
110
111 u8 rx_unit;
110}; 112};
111 113
112/********************************************************************/ 114/********************************************************************/
@@ -136,6 +138,46 @@ static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
136 return scratch; 138 return scratch;
137} 139}
138 140
141static u8 if_sdio_read_rx_unit(struct if_sdio_card *card)
142{
143 int ret;
144 u8 rx_unit;
145
146 rx_unit = sdio_readb(card->func, IF_SDIO_RX_UNIT, &ret);
147
148 if (ret)
149 rx_unit = 0;
150
151 return rx_unit;
152}
153
154static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
155{
156 int ret;
157 u16 rx_len;
158
159 switch (card->model) {
160 case IF_SDIO_MODEL_8385:
161 case IF_SDIO_MODEL_8686:
162 rx_len = if_sdio_read_scratch(card, &ret);
163 break;
164 case IF_SDIO_MODEL_8688:
165 default: /* for newer chipsets */
166 rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
167 if (!ret)
168 rx_len <<= card->rx_unit;
169 else
170 rx_len = 0xffff; /* invalid length */
171
172 break;
173 }
174
175 if (err)
176 *err = ret;
177
178 return rx_len;
179}
180
139static int if_sdio_handle_cmd(struct if_sdio_card *card, 181static int if_sdio_handle_cmd(struct if_sdio_card *card,
140 u8 *buffer, unsigned size) 182 u8 *buffer, unsigned size)
141{ 183{
@@ -254,7 +296,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
254 296
255 lbs_deb_enter(LBS_DEB_SDIO); 297 lbs_deb_enter(LBS_DEB_SDIO);
256 298
257 size = if_sdio_read_scratch(card, &ret); 299 size = if_sdio_read_rx_len(card, &ret);
258 if (ret) 300 if (ret)
259 goto out; 301 goto out;
260 302
@@ -923,10 +965,21 @@ static int if_sdio_probe(struct sdio_func *func,
923 965
924 priv->fw_ready = 1; 966 priv->fw_ready = 1;
925 967
968 sdio_claim_host(func);
969
970 /*
971 * Get rx_unit if the chip is SD8688 or newer.
972 * SD8385 & SD8686 do not have rx_unit.
973 */
974 if ((card->model != IF_SDIO_MODEL_8385)
975 && (card->model != IF_SDIO_MODEL_8686))
976 card->rx_unit = if_sdio_read_rx_unit(card);
977 else
978 card->rx_unit = 0;
979
926 /* 980 /*
927 * Enable interrupts now that everything is set up 981 * Enable interrupts now that everything is set up
928 */ 982 */
929 sdio_claim_host(func);
930 sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret); 983 sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
931 sdio_release_host(func); 984 sdio_release_host(func);
932 if (ret) 985 if (ret)
diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h
index cea343f9afd1..d3a4fbe07692 100644
--- a/drivers/net/wireless/libertas/if_sdio.h
+++ b/drivers/net/wireless/libertas/if_sdio.h
@@ -44,6 +44,9 @@
44#define IF_SDIO_SCRATCH_OLD 0x80fe 44#define IF_SDIO_SCRATCH_OLD 0x80fe
45#define IF_SDIO_FIRMWARE_OK 0xfedc 45#define IF_SDIO_FIRMWARE_OK 0xfedc
46 46
47#define IF_SDIO_RX_LEN 0x42
48#define IF_SDIO_RX_UNIT 0x43
49
47#define IF_SDIO_EVENT 0x80fc 50#define IF_SDIO_EVENT 0x80fc
48 51
49#define IF_SDIO_BLOCK_SIZE 256 52#define IF_SDIO_BLOCK_SIZE 256