kernel: ssb: add PCI ID 0x4351
[openwrt.git] / target / linux / generic / patches-3.14 / 020-ssb_update.patch
1 --- a/drivers/ssb/b43_pci_bridge.c
2 +++ b/drivers/ssb/b43_pci_bridge.c
3 @@ -38,6 +38,7 @@ static const struct pci_device_id b43_pc
4         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) },
5         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) },
6         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) },
7 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4351) },
8         { 0, },
9  };
10  MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl);
11 --- a/drivers/ssb/pci.c
12 +++ b/drivers/ssb/pci.c
13 @@ -326,13 +326,13 @@ err_ctlreg:
14         return err;
15  }
16  
17 -static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
18 -                              u16 mask, u16 shift)
19 +static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset,
20 +                               u16 mask, u16 shift)
21  {
22         u16 v;
23         u8 gain;
24  
25 -       v = in[SPOFF(SSB_SPROM1_AGAIN)];
26 +       v = in[SPOFF(offset)];
27         gain = (v & mask) >> shift;
28         if (gain == 0xFF)
29                 gain = 2; /* If unset use 2dBm */
30 @@ -416,12 +416,14 @@ static void sprom_extract_r123(struct ss
31         SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
32  
33         /* Extract the antenna gain values. */
34 -       out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
35 -                                                   SSB_SPROM1_AGAIN_BG,
36 -                                                   SSB_SPROM1_AGAIN_BG_SHIFT);
37 -       out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
38 -                                                   SSB_SPROM1_AGAIN_A,
39 -                                                   SSB_SPROM1_AGAIN_A_SHIFT);
40 +       out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
41 +                                                    SSB_SPROM1_AGAIN,
42 +                                                    SSB_SPROM1_AGAIN_BG,
43 +                                                    SSB_SPROM1_AGAIN_BG_SHIFT);
44 +       out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
45 +                                                    SSB_SPROM1_AGAIN,
46 +                                                    SSB_SPROM1_AGAIN_A,
47 +                                                    SSB_SPROM1_AGAIN_A_SHIFT);
48         if (out->revision >= 2)
49                 sprom_extract_r23(out, in);
50  }
51 @@ -468,7 +470,15 @@ static void sprom_extract_r458(struct ss
52  
53  static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
54  {
55 +       static const u16 pwr_info_offset[] = {
56 +               SSB_SPROM4_PWR_INFO_CORE0, SSB_SPROM4_PWR_INFO_CORE1,
57 +               SSB_SPROM4_PWR_INFO_CORE2, SSB_SPROM4_PWR_INFO_CORE3
58 +       };
59         u16 il0mac_offset;
60 +       int i;
61 +
62 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
63 +                    ARRAY_SIZE(out->core_pwr_info));
64  
65         if (out->revision == 4)
66                 il0mac_offset = SSB_SPROM4_IL0MAC;
67 @@ -524,14 +534,59 @@ static void sprom_extract_r45(struct ssb
68         }
69  
70         /* Extract the antenna gain values. */
71 -       SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
72 -            SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
73 -       SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
74 -            SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
75 -       SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
76 -            SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
77 -       SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
78 -            SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
79 +       out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
80 +                                                    SSB_SPROM4_AGAIN01,
81 +                                                    SSB_SPROM4_AGAIN0,
82 +                                                    SSB_SPROM4_AGAIN0_SHIFT);
83 +       out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
84 +                                                    SSB_SPROM4_AGAIN01,
85 +                                                    SSB_SPROM4_AGAIN1,
86 +                                                    SSB_SPROM4_AGAIN1_SHIFT);
87 +       out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
88 +                                                    SSB_SPROM4_AGAIN23,
89 +                                                    SSB_SPROM4_AGAIN2,
90 +                                                    SSB_SPROM4_AGAIN2_SHIFT);
91 +       out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
92 +                                                    SSB_SPROM4_AGAIN23,
93 +                                                    SSB_SPROM4_AGAIN3,
94 +                                                    SSB_SPROM4_AGAIN3_SHIFT);
95 +
96 +       /* Extract cores power info info */
97 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
98 +               u16 o = pwr_info_offset[i];
99 +
100 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
101 +                       SSB_SPROM4_2G_ITSSI, SSB_SPROM4_2G_ITSSI_SHIFT);
102 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
103 +                       SSB_SPROM4_2G_MAXP, 0);
104 +
105 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SPROM4_2G_PA_0, ~0, 0);
106 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SPROM4_2G_PA_1, ~0, 0);
107 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SPROM4_2G_PA_2, ~0, 0);
108 +               SPEX(core_pwr_info[i].pa_2g[3], o + SSB_SPROM4_2G_PA_3, ~0, 0);
109 +
110 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
111 +                       SSB_SPROM4_5G_ITSSI, SSB_SPROM4_5G_ITSSI_SHIFT);
112 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
113 +                       SSB_SPROM4_5G_MAXP, 0);
114 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM4_5GHL_MAXP,
115 +                       SSB_SPROM4_5GH_MAXP, 0);
116 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM4_5GHL_MAXP,
117 +                       SSB_SPROM4_5GL_MAXP, SSB_SPROM4_5GL_MAXP_SHIFT);
118 +
119 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SPROM4_5GL_PA_0, ~0, 0);
120 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SPROM4_5GL_PA_1, ~0, 0);
121 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SPROM4_5GL_PA_2, ~0, 0);
122 +               SPEX(core_pwr_info[i].pa_5gl[3], o + SSB_SPROM4_5GL_PA_3, ~0, 0);
123 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SPROM4_5G_PA_0, ~0, 0);
124 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SPROM4_5G_PA_1, ~0, 0);
125 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SPROM4_5G_PA_2, ~0, 0);
126 +               SPEX(core_pwr_info[i].pa_5g[3], o + SSB_SPROM4_5G_PA_3, ~0, 0);
127 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SPROM4_5GH_PA_0, ~0, 0);
128 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SPROM4_5GH_PA_1, ~0, 0);
129 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SPROM4_5GH_PA_2, ~0, 0);
130 +               SPEX(core_pwr_info[i].pa_5gh[3], o + SSB_SPROM4_5GH_PA_3, ~0, 0);
131 +       }
132  
133         sprom_extract_r458(out, in);
134  
135 @@ -621,14 +676,22 @@ static void sprom_extract_r8(struct ssb_
136         SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
137  
138         /* Extract the antenna gain values. */
139 -       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
140 -            SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
141 -       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
142 -            SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
143 -       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
144 -            SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
145 -       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
146 -            SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
147 +       out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
148 +                                                    SSB_SPROM8_AGAIN01,
149 +                                                    SSB_SPROM8_AGAIN0,
150 +                                                    SSB_SPROM8_AGAIN0_SHIFT);
151 +       out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
152 +                                                    SSB_SPROM8_AGAIN01,
153 +                                                    SSB_SPROM8_AGAIN1,
154 +                                                    SSB_SPROM8_AGAIN1_SHIFT);
155 +       out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
156 +                                                    SSB_SPROM8_AGAIN23,
157 +                                                    SSB_SPROM8_AGAIN2,
158 +                                                    SSB_SPROM8_AGAIN2_SHIFT);
159 +       out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
160 +                                                    SSB_SPROM8_AGAIN23,
161 +                                                    SSB_SPROM8_AGAIN3,
162 +                                                    SSB_SPROM8_AGAIN3_SHIFT);
163  
164         /* Extract cores power info info */
165         for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
166 --- a/include/linux/ssb/ssb.h
167 +++ b/include/linux/ssb/ssb.h
168 @@ -33,6 +33,7 @@ struct ssb_sprom {
169         u8 et1phyaddr;          /* MII address for enet1 */
170         u8 et0mdcport;          /* MDIO for enet0 */
171         u8 et1mdcport;          /* MDIO for enet1 */
172 +       u16 dev_id;             /* Device ID overriding e.g. PCI ID */
173         u16 board_rev;          /* Board revision number from SPROM. */
174         u16 board_num;          /* Board number from SPROM. */
175         u16 board_type;         /* Board type from SPROM. */
176 --- a/include/linux/ssb/ssb_regs.h
177 +++ b/include/linux/ssb/ssb_regs.h
178 @@ -345,6 +345,43 @@
179  #define  SSB_SPROM4_TXPID5GH2_SHIFT    0
180  #define  SSB_SPROM4_TXPID5GH3          0xFF00
181  #define  SSB_SPROM4_TXPID5GH3_SHIFT    8
182 +
183 +/* There are 4 blocks with power info sharing the same layout */
184 +#define SSB_SPROM4_PWR_INFO_CORE0      0x0080
185 +#define SSB_SPROM4_PWR_INFO_CORE1      0x00AE
186 +#define SSB_SPROM4_PWR_INFO_CORE2      0x00DC
187 +#define SSB_SPROM4_PWR_INFO_CORE3      0x010A
188 +
189 +#define SSB_SPROM4_2G_MAXP_ITSSI       0x00    /* 2 GHz ITSSI and 2 GHz Max Power */
190 +#define  SSB_SPROM4_2G_MAXP            0x00FF
191 +#define  SSB_SPROM4_2G_ITSSI           0xFF00
192 +#define  SSB_SPROM4_2G_ITSSI_SHIFT     8
193 +#define SSB_SPROM4_2G_PA_0             0x02    /* 2 GHz power amp */
194 +#define SSB_SPROM4_2G_PA_1             0x04
195 +#define SSB_SPROM4_2G_PA_2             0x06
196 +#define SSB_SPROM4_2G_PA_3             0x08
197 +#define SSB_SPROM4_5G_MAXP_ITSSI       0x0A    /* 5 GHz ITSSI and 5.3 GHz Max Power */
198 +#define  SSB_SPROM4_5G_MAXP            0x00FF
199 +#define  SSB_SPROM4_5G_ITSSI           0xFF00
200 +#define  SSB_SPROM4_5G_ITSSI_SHIFT     8
201 +#define SSB_SPROM4_5GHL_MAXP           0x0C    /* 5.2 GHz and 5.8 GHz Max Power */
202 +#define  SSB_SPROM4_5GH_MAXP           0x00FF
203 +#define  SSB_SPROM4_5GL_MAXP           0xFF00
204 +#define  SSB_SPROM4_5GL_MAXP_SHIFT     8
205 +#define SSB_SPROM4_5G_PA_0             0x0E    /* 5.3 GHz power amp */
206 +#define SSB_SPROM4_5G_PA_1             0x10
207 +#define SSB_SPROM4_5G_PA_2             0x12
208 +#define SSB_SPROM4_5G_PA_3             0x14
209 +#define SSB_SPROM4_5GL_PA_0            0x16    /* 5.2 GHz power amp */
210 +#define SSB_SPROM4_5GL_PA_1            0x18
211 +#define SSB_SPROM4_5GL_PA_2            0x1A
212 +#define SSB_SPROM4_5GL_PA_3            0x1C
213 +#define SSB_SPROM4_5GH_PA_0            0x1E    /* 5.8 GHz power amp */
214 +#define SSB_SPROM4_5GH_PA_1            0x20
215 +#define SSB_SPROM4_5GH_PA_2            0x22
216 +#define SSB_SPROM4_5GH_PA_3            0x24
217 +
218 +/* TODO: Make it deprecated */
219  #define SSB_SPROM4_MAXP_BG             0x0080  /* Max Power BG in path 1 */
220  #define  SSB_SPROM4_MAXP_BG_MASK       0x00FF  /* Mask for Max Power BG */
221  #define  SSB_SPROM4_ITSSI_BG           0xFF00  /* Mask for path 1 itssi_bg */
222 --- a/arch/mips/bcm47xx/sprom.c
223 +++ b/arch/mips/bcm47xx/sprom.c
224 @@ -168,6 +168,7 @@ static void nvram_read_alpha2(const char
225  static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
226                                         const char *prefix, bool fallback)
227  {
228 +       nvram_read_u16(prefix, NULL, "devid", &sprom->dev_id, 0, fallback);
229         nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff, fallback);
230         nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff, fallback);
231         nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff, fallback);