brcm47xx: add fallback sprom for pci devices without an own sprom.
[openwrt.git] / target / linux / brcm63xx / patches-2.6.37 / 500-ssb-add-callback-for-sprom.patch
1 From 62a518124cff3970d99f7ccdab457f4289e3b982 Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Sat, 30 Apr 2011 15:42:30 +0200
4 Subject: [PATCH 1/4] ssb: add callback for sprom
5
6
7 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
8 ---
9  arch/mips/bcm63xx/boards/board_bcm963xx.c |   16 ++++++++++++++--
10  drivers/ssb/pci.c                         |   13 ++++++++-----
11  drivers/ssb/sprom.c                       |   26 +++++++++++++++-----------
12  drivers/ssb/ssb_private.h                 |    2 +-
13  include/linux/ssb/ssb.h                   |    3 ++-
14  5 files changed, 40 insertions(+), 20 deletions(-)
15
16 --- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
17 +++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
18 @@ -1927,6 +1927,17 @@ static struct ssb_sprom bcm63xx_sprom =
19         .boardflags_lo          = 0x2848,
20         .boardflags_hi          = 0x0000,
21  };
22 +
23 +int bcm63xx_get_fallback_sprom(struct ssb_bus *bus)
24 +{
25 +       if (bus->bustype == SSB_BUSTYPE_PCI) {
26 +               memcpy(&bus->sprom, &bcm63xx_sprom, sizeof(struct ssb_sprom));
27 +               return 0;
28 +       } else {
29 +               printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
30 +               return -EINVAL;
31 +       }
32 +}
33  #endif
34  
35  /*
36 @@ -2111,8 +2122,9 @@ void __init board_prom_init(void)
37         if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
38                 memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
39                 memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
40 -               if (ssb_arch_set_fallback_sprom(&bcm63xx_sprom) < 0)
41 -                       printk(KERN_ERR "failed to register fallback SPROM\n");
42 +               if (ssb_arch_register_fallback_sprom(
43 +                               &bcm63xx_get_fallback_sprom) < 0)
44 +                       printk(KERN_ERR PFX "failed to register fallback SPROM\n");
45         }
46  #endif
47  }
48 --- a/drivers/ssb/pci.c
49 +++ b/drivers/ssb/pci.c
50 @@ -662,7 +662,6 @@ static int sprom_extract(struct ssb_bus
51  static int ssb_pci_sprom_get(struct ssb_bus *bus,
52                              struct ssb_sprom *sprom)
53  {
54 -       const struct ssb_sprom *fallback;
55         int err;
56         u16 *buf;
57  
58 @@ -707,10 +706,14 @@ static int ssb_pci_sprom_get(struct ssb_
59                 if (err) {
60                         /* All CRC attempts failed.
61                          * Maybe there is no SPROM on the device?
62 -                        * If we have a fallback, use that. */
63 -                       fallback = ssb_get_fallback_sprom();
64 -                       if (fallback) {
65 -                               memcpy(sprom, fallback, sizeof(*sprom));
66 +                        * Now we ask the arch code if there is some sprom
67 +                        * avaliable for this device in some other storage */
68 +                       err = ssb_fill_sprom_with_fallback(bus);
69 +                       if (err) {
70 +                               ssb_printk(KERN_WARNING PFX "WARNING: Using"
71 +                                          " fallback SPROM failed (err %d)\n",
72 +                                          err);
73 +                       } else {
74                                 err = 0;
75                                 goto out_free;
76                         }
77 --- a/drivers/ssb/sprom.c
78 +++ b/drivers/ssb/sprom.c
79 @@ -17,7 +17,7 @@
80  #include <linux/slab.h>
81  
82  
83 -static const struct ssb_sprom *fallback_sprom;
84 +static int(*get_fallback_sprom)(struct ssb_bus *dev);
85  
86  
87  static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
88 @@ -145,13 +145,14 @@ out:
89  }
90  
91  /**
92 - * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
93 + * ssb_arch_register_fallback_sprom - Registers a method providing a fallback
94 + * SPROM if no SPROM is found.
95   *
96 - * @sprom: The SPROM data structure to register.
97 + * @sprom_callback: The callbcak function.
98   *
99 - * With this function the architecture implementation may register a fallback
100 - * SPROM data structure. The fallback is only used for PCI based SSB devices,
101 - * where no valid SPROM can be found in the shadow registers.
102 + * With this function the architecture implementation may register a callback
103 + * handler which wills the SPROM data structure. The fallback is only used for
104 + * PCI based SSB devices, where no valid SPROM can be found in the shadow registers.
105   *
106   * This function is useful for weird architectures that have a half-assed SSB device
107   * hardwired to their PCI bus.
108 @@ -163,18 +164,21 @@ out:
109   *
110   * This function is available for architecture code, only. So it is not exported.
111   */
112 -int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
113 +int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus))
114  {
115 -       if (fallback_sprom)
116 +       if (get_fallback_sprom)
117                 return -EEXIST;
118 -       fallback_sprom = sprom;
119 +       get_fallback_sprom = sprom_callback;
120  
121         return 0;
122  }
123  
124 -const struct ssb_sprom *ssb_get_fallback_sprom(void)
125 +int ssb_fill_sprom_with_fallback(struct ssb_bus *bus)
126  {
127 -       return fallback_sprom;
128 +       if (!get_fallback_sprom)
129 +               return -ENOENT;
130 +
131 +       return get_fallback_sprom(bus);
132  }
133  
134  /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
135 --- a/drivers/ssb/ssb_private.h
136 +++ b/drivers/ssb/ssb_private.h
137 @@ -171,7 +171,7 @@ ssize_t ssb_attr_sprom_store(struct ssb_
138                              const char *buf, size_t count,
139                              int (*sprom_check_crc)(const u16 *sprom, size_t size),
140                              int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
141 -extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
142 +extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus);
143  
144  
145  /* core.c */
146 --- a/include/linux/ssb/ssb.h
147 +++ b/include/linux/ssb/ssb.h
148 @@ -404,7 +404,8 @@ extern bool ssb_is_sprom_available(struc
149  
150  /* Set a fallback SPROM.
151   * See kdoc at the function definition for complete documentation. */
152 -extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
153 +extern int ssb_arch_register_fallback_sprom(
154 +               int (*sprom_callback)(struct ssb_bus *bus));
155  
156  /* Suspend a SSB bus.
157   * Call this from the parent bus suspend routine. */