aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut@gmail.com>2009-08-20 22:08:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-28 14:40:35 -0400
commit9d45368a3825349d8ba686bc36df589d16577dd4 (patch)
tree489a6243296ba9ef204618befafcaefa4f7c6c09 /drivers/net/wireless/libertas
parentca4fe30097d700c595c13362200083650759e104 (diff)
libertas: Add support for Marvell Libertas CF8305
The CF8305 is a very old silicon running firmware version 3.0 . This card also needs some special treatment as it's so old it can't do unaligned register access. But since that happens only at one place, there were no changes made to the register access functions, but instead that particular place was fixed. Also, this card uses only one-stage firmware which is loaded the same way as helper firmware. The second-stage firmware isn't loaded on this card and doesn't therefore have to be supplied. Signed-off-by: Marek Vasut <marek.vasut@gmail.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_cs.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index f658fd6a2c0c..62381768f2d5 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -59,6 +59,7 @@ struct if_cs_card {
59 struct pcmcia_device *p_dev; 59 struct pcmcia_device *p_dev;
60 struct lbs_private *priv; 60 struct lbs_private *priv;
61 void __iomem *iobase; 61 void __iomem *iobase;
62 bool align_regs;
62}; 63};
63 64
64 65
@@ -274,16 +275,25 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
274#define IF_CS_PRODUCT_ID 0x0000001C 275#define IF_CS_PRODUCT_ID 0x0000001C
275#define IF_CS_CF8385_B1_REV 0x12 276#define IF_CS_CF8385_B1_REV 0x12
276#define IF_CS_CF8381_B3_REV 0x04 277#define IF_CS_CF8381_B3_REV 0x04
278#define IF_CS_CF8305_B1_REV 0x03
277 279
278/* 280/*
279 * Used to detect other cards than CF8385 since their revisions of silicon 281 * Used to detect other cards than CF8385 since their revisions of silicon
280 * doesn't match those from CF8385, eg. CF8381 B3 works with this driver. 282 * doesn't match those from CF8385, eg. CF8381 B3 works with this driver.
281 */ 283 */
284#define CF8305_MANFID 0x02db
285#define CF8305_CARDID 0x8103
282#define CF8381_MANFID 0x02db 286#define CF8381_MANFID 0x02db
283#define CF8381_CARDID 0x6064 287#define CF8381_CARDID 0x6064
284#define CF8385_MANFID 0x02df 288#define CF8385_MANFID 0x02df
285#define CF8385_CARDID 0x8103 289#define CF8385_CARDID 0x8103
286 290
291static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev)
292{
293 return (p_dev->manf_id == CF8305_MANFID &&
294 p_dev->card_id == CF8305_CARDID);
295}
296
287static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev) 297static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
288{ 298{
289 return (p_dev->manf_id == CF8381_MANFID && 299 return (p_dev->manf_id == CF8381_MANFID &&
@@ -556,7 +566,15 @@ static int if_cs_prog_helper(struct if_cs_card *card)
556 566
557 lbs_deb_enter(LBS_DEB_CS); 567 lbs_deb_enter(LBS_DEB_CS);
558 568
559 scratch = if_cs_read8(card, IF_CS_SCRATCH); 569 /*
570 * This is the only place where an unaligned register access happens on
571 * the CF8305 card, therefore for the sake of speed of the driver, we do
572 * the alignment correction here.
573 */
574 if (card->align_regs)
575 scratch = if_cs_read16(card, IF_CS_SCRATCH) >> 8;
576 else
577 scratch = if_cs_read8(card, IF_CS_SCRATCH);
560 578
561 /* "If the value is 0x5a, the firmware is already 579 /* "If the value is 0x5a, the firmware is already
562 * downloaded successfully" 580 * downloaded successfully"
@@ -880,8 +898,24 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
880 p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, 898 p_dev->irq.AssignedIRQ, p_dev->io.BasePort1,
881 p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); 899 p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
882 900
901 /*
902 * Most of the libertas cards can do unaligned register access, but some
903 * weird ones can not. That's especially true for the CF8305 card.
904 */
905 card->align_regs = 0;
906
883 /* Check if we have a current silicon */ 907 /* Check if we have a current silicon */
884 prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); 908 prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
909 if (if_cs_hw_is_cf8305(p_dev)) {
910 card->align_regs = 1;
911 if (prod_id < IF_CS_CF8305_B1_REV) {
912 lbs_pr_err("old chips like 8305 rev B3 "
913 "aren't supported\n");
914 ret = -ENODEV;
915 goto out2;
916 }
917 }
918
885 if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) { 919 if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) {
886 lbs_pr_err("old chips like 8381 rev B3 aren't supported\n"); 920 lbs_pr_err("old chips like 8381 rev B3 aren't supported\n");
887 ret = -ENODEV; 921 ret = -ENODEV;
@@ -896,7 +930,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
896 930
897 /* Load the firmware early, before calling into libertas.ko */ 931 /* Load the firmware early, before calling into libertas.ko */
898 ret = if_cs_prog_helper(card); 932 ret = if_cs_prog_helper(card);
899 if (ret == 0) 933 if (ret == 0 && !if_cs_hw_is_cf8305(p_dev))
900 ret = if_cs_prog_real(card); 934 ret = if_cs_prog_real(card);
901 if (ret) 935 if (ret)
902 goto out2; 936 goto out2;
@@ -976,6 +1010,7 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
976/********************************************************************/ 1010/********************************************************************/
977 1011
978static struct pcmcia_device_id if_cs_ids[] = { 1012static struct pcmcia_device_id if_cs_ids[] = {
1013 PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
979 PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), 1014 PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
980 PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), 1015 PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
981 PCMCIA_DEVICE_NULL, 1016 PCMCIA_DEVICE_NULL,