Root/package/madwifi/patches/384-hwdetect.patch

1--- a/ath/if_ath.c
2+++ b/ath/if_ath.c
3@@ -62,6 +62,7 @@
4 #include <linux/if_arp.h>
5 #include <linux/rtnetlink.h>
6 #include <linux/time.h>
7+#include <linux/pci.h>
8 #include <asm/uaccess.h>
9 
10 #include "if_ethersubr.h" /* for ETHER_IS_MULTICAST */
11@@ -401,6 +402,15 @@ static int outdoor = -1;
12 static int xchanmode = -1;
13 static int beacon_cal = 1;
14 
15+static const struct ath_hw_detect generic_hw_info = {
16+ .vendor_name = "Unknown",
17+ .card_name = "Generic",
18+ .vendor = PCI_ANY_ID,
19+ .id = PCI_ANY_ID,
20+ .subvendor = PCI_ANY_ID,
21+ .subid = PCI_ANY_ID
22+};
23+
24 static const char *hal_status_desc[] = {
25     "No error",
26     "No hardware present or device not yet supported",
27@@ -542,6 +552,8 @@ ath_attach(u_int16_t devid, struct net_d
28     DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid);
29 #endif
30 
31+ sc->sc_hwinfo = &generic_hw_info;
32+
33     /* Allocate space for dynamically determined maximum VAP count */
34     sc->sc_bslot =
35         kmalloc(ath_maxvaps * sizeof(struct ieee80211vap*), GFP_KERNEL);
36@@ -1508,6 +1520,29 @@ ath_vap_create(struct ieee80211com *ic,
37     return vap;
38 }
39 
40+void
41+ath_hw_detect(struct ath_softc *sc, const struct ath_hw_detect *cards, int n_cards, u32 vendor, u32 id, u32 subvendor, u32 subid)
42+{
43+ int i;
44+
45+ for (i = 0; i < n_cards; i++) {
46+ const struct ath_hw_detect *c = &cards[i];
47+
48+ if ((c->vendor != PCI_ANY_ID) && c->vendor != vendor)
49+ continue;
50+ if ((c->id != PCI_ANY_ID) && c->id != id)
51+ continue;
52+ if ((c->subvendor != PCI_ANY_ID) && c->subvendor != subvendor)
53+ continue;
54+ if ((c->subid != PCI_ANY_ID) && c->subid != subid)
55+ continue;
56+
57+ sc->sc_hwinfo = c;
58+ sc->sc_poweroffset = c->poweroffset;
59+ break;
60+ }
61+}
62+
63 static void
64 ath_vap_delete(struct ieee80211vap *vap)
65 {
66@@ -10225,6 +10260,7 @@ static u_int32_t
67 ath_set_clamped_maxtxpower(struct ath_softc *sc,
68         u_int32_t new_clamped_maxtxpower)
69 {
70+ new_clamped_maxtxpower -= sc->sc_poweroffset;
71     (void)ath_hal_settxpowlimit(sc->sc_ah, new_clamped_maxtxpower);
72     return ath_get_clamped_maxtxpower(sc);
73 }
74@@ -10238,6 +10274,7 @@ ath_get_clamped_maxtxpower(struct ath_so
75 {
76     u_int32_t clamped_maxtxpower;
77     (void)ath_hal_getmaxtxpow(sc->sc_ah, &clamped_maxtxpower);
78+ clamped_maxtxpower += sc->sc_poweroffset;
79     return clamped_maxtxpower;
80 }
81 
82@@ -10821,6 +10858,12 @@ ath_ioctl(struct net_device *dev, struct
83  * is to add module parameters.
84  */
85 
86+/* sysctls for hardware info */
87+enum {
88+ ATH_CARD_VENDOR,
89+ ATH_CARD_NAME,
90+};
91+
92 /*
93  * Dynamic (i.e. per-device) sysctls. These are automatically
94  * mirrored in /proc/sys.
95@@ -10900,6 +10943,38 @@ ath_sysctl_get_intmit(struct ath_softc *
96 }
97 
98 static int
99+ATH_SYSCTL_DECL(ath_sysctl_hwinfo, ctl, write, filp, buffer, lenp, ppos)
100+{
101+ struct ath_softc *sc = ctl->extra1;
102+ struct ath_hal *ah = sc->sc_ah;
103+ int ret = 0;
104+
105+ if (write)
106+ return -EINVAL;
107+
108+ ATH_LOCK(sc);
109+ switch((long)ctl->extra2) {
110+ case ATH_CARD_VENDOR:
111+ ctl->data = (char *)sc->sc_hwinfo->vendor_name;
112+ break;
113+ case ATH_CARD_NAME:
114+ ctl->data = (char *)sc->sc_hwinfo->card_name;
115+ break;
116+ default:
117+ ret = -EINVAL;
118+ break;
119+ }
120+ if (ret == 0) {
121+ ctl->maxlen = strlen(ctl->data);
122+ ret = ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp,
123+ buffer, lenp, ppos);
124+ }
125+ ATH_UNLOCK(sc);
126+
127+ return ret;
128+}
129+
130+static int
131 ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
132 {
133     struct ath_softc *sc = ctl->extra1;
134@@ -11179,6 +11254,24 @@ static int maxint = 0x7fffffff; /* 32-b
135 
136 static const ctl_table ath_sysctl_template[] = {
137     { .ctl_name = CTL_AUTO,
138+ .procname = "dev_vendor",
139+ .mode = 0644,
140+ .proc_handler = ath_sysctl_hwinfo,
141+ .strategy = &sysctl_string,
142+ .data = "N/A",
143+ .maxlen = 1,
144+ .extra2 = (void *)ATH_CARD_VENDOR,
145+ },
146+ { .ctl_name = CTL_AUTO,
147+ .procname = "dev_name",
148+ .mode = 0644,
149+ .proc_handler = ath_sysctl_hwinfo,
150+ .strategy = &sysctl_string,
151+ .data = "N/A",
152+ .maxlen = 1,
153+ .extra2 = (void *)ATH_CARD_NAME,
154+ },
155+ { .ctl_name = CTL_AUTO,
156       .procname = "slottime",
157       .mode = 0644,
158       .proc_handler = ath_sysctl_halparam,
159--- a/ath/if_athvar.h
160+++ b/ath/if_athvar.h
161@@ -168,12 +168,16 @@ static inline struct net_device *_alloc_
162       void __user *buffer, size_t *lenp)
163 #define ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
164     proc_dointvec(ctl, write, filp, buffer, lenp)
165+#define ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
166+ proc_dostring(ctl, write, filp, buffer, lenp)
167 #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) */
168 #define ATH_SYSCTL_DECL(f, ctl, write, filp, buffer, lenp, ppos) \
169     f(ctl_table *ctl, int write, struct file *filp, \
170       void __user *buffer, size_t *lenp, loff_t *ppos)
171 #define ATH_SYSCTL_PROC_DOINTVEC(ctl, write, filp, buffer, lenp, ppos) \
172     proc_dointvec(ctl, write, filp, buffer, lenp, ppos)
173+#define ATH_SYSCTL_PROC_DOSTRING(ctl, write, filp, buffer, lenp, ppos) \
174+ proc_dostring(ctl, write, filp, buffer, lenp, ppos)
175 #endif
176 
177 #define ATH_TIMEOUT 1000
178@@ -469,6 +473,7 @@ struct ath_hal;
179 struct ath_desc;
180 struct ath_ratectrl;
181 struct ath_tx99;
182+struct ath_hw_detect;
183 struct proc_dir_entry;
184 
185 /*
186@@ -629,6 +634,7 @@ struct ath_softc {
187     struct ath_ratectrl *sc_rc; /* tx rate control support */
188     struct ath_tx99 *sc_tx99; /* tx99 support */
189     void (*sc_setdefantenna)(struct ath_softc *, u_int);
190+ const struct ath_hw_detect *sc_hwinfo;
191 
192     unsigned int sc_invalid:1; /* being detached */
193     unsigned int sc_mrretry:1; /* multi-rate retry support */
194@@ -683,6 +689,7 @@ struct ath_softc {
195     const HAL_RATE_TABLE *sc_quarter_rates; /* quarter rate table */
196     HAL_OPMODE sc_opmode; /* current hal operating mode */
197     enum ieee80211_phymode sc_curmode; /* current phy mode */
198+ u_int sc_poweroffset; /* hardware power offset */
199     u_int16_t sc_curtxpow; /* current tx power limit */
200     u_int16_t sc_curaid; /* current association id */
201     HAL_CHANNEL sc_curchan; /* current h/w channel */
202@@ -929,4 +936,16 @@ int ar_device(int devid);
203 
204 void ath_radar_detected(struct ath_softc *sc, const char* message);
205 
206+struct ath_hw_detect {
207+ const char *vendor_name;
208+ const char *card_name;
209+ u32 vendor;
210+ u32 id;
211+ u32 subvendor;
212+ u32 subid;
213+ u32 poweroffset;
214+};
215+
216+extern void ath_hw_detect(struct ath_softc *sc, const struct ath_hw_detect *cards, int n_cards, u32 vendor, u32 id, u32 subvendor, u32 subid);
217+
218 #endif /* _DEV_ATH_ATHVAR_H */
219--- a/ath/if_ath_ahb.c
220+++ b/ath/if_ath_ahb.c
221@@ -20,6 +20,7 @@
222 #include <linux/netdevice.h>
223 #include <linux/cache.h>
224 #include <linux/platform_device.h>
225+#include <linux/pci.h>
226 
227 #include <asm/io.h>
228 #include <asm/uaccess.h>
229@@ -181,12 +182,32 @@ exit_ath_wmac(u_int16_t wlanNum, struct
230     return 0;
231 }
232 
233+static const char ubnt[] = "Ubiquiti Networks";
234+/* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
235+static const struct ath_hw_detect cards[] = {
236+ { ubnt, "PowerStation2 (18V)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb102 },
237+ { ubnt, "PowerStation2 (16D)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb202 },
238+ { ubnt, "PowerStation2 (EXT)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb302 },
239+ { ubnt, "PowerStation5 (22V)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb105 },
240+ { ubnt, "PowerStation5 (EXT)", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xb305 },
241+ { ubnt, "WispStation5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa105 },
242+ { ubnt, "LiteStation2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa002 },
243+ { ubnt, "LiteStation5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xa005 },
244+ { ubnt, "NanoStation2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc002 },
245+ { ubnt, "NanoStation5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc005 },
246+ { ubnt, "NanoStation Loco2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc102 },
247+ { ubnt, "NanoStation Loco5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc105 },
248+ { ubnt, "Bullet2", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc202 },
249+ { ubnt, "Bullet5", PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0xc205 },
250+};
251+
252 static int
253 init_ath_wmac(u_int16_t devid, u_int16_t wlanNum, struct ar531x_config *config)
254 {
255     const char *athname;
256     struct net_device *dev;
257     struct ath_ahb_softc *sc;
258+ u16 *radio_data;
259 
260     if (((wlanNum != 0) && (wlanNum != 1)) ||
261         (sclist[wlanNum] != NULL))
262@@ -248,6 +269,16 @@ init_ath_wmac(u_int16_t devid, u_int16_t
263     sc->aps_sc.sc_softled = 1; /* SoftLED over GPIO */
264     sc->aps_sc.sc_ledpin = config->board->sysLedGpio;
265     sc->aps_sc.sc_invalid = 0;
266+ radio_data = (u16 *) config->radio;
267+ if (radio_data) {
268+ u16 vendor, id, subvendor, subid;
269+ vendor = radio_data[1];
270+ id = radio_data[0];
271+ subvendor = radio_data[8];
272+ subid = radio_data[7];
273+ ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards), vendor, id, subvendor, subid);
274+ }
275+
276     return 0;
277 
278  bad4:
279--- a/ath/if_ath_pci.c
280+++ b/ath/if_ath_pci.c
281@@ -123,6 +123,33 @@ static u16 ath_devidmap[][2] = {
282     { 0xff1a, 0x001a }
283 };
284 
285+static const char ubnt[] = "Ubiquiti Networks";
286+/* { vendorname, cardname, vendorid, cardid, subsys vendorid, subsys id, poweroffset } */
287+static const struct ath_hw_detect cards[] = {
288+ { ubnt, "XR2", 0x168c, 0x001b, 0x0777, 0x3002, 10 },
289+ { ubnt, "XR2", 0x168c, 0x001b, 0x7777, 0x3002, 10 },
290+ { ubnt, "XR2.3", 0x168c, 0x001b, 0x0777, 0x3b02, 10 },
291+ { ubnt, "XR2.6", 0x168c, 0x001b, 0x0777, 0x3c02, 10 },
292+ { ubnt, "XR3-2.8", 0x168c, 0x001b, 0x0777, 0x3b03, 10 },
293+ { ubnt, "XR3-3.6", 0x168c, 0x001b, 0x0777, 0x3c03, 10 },
294+ { ubnt, "XR3", 0x168c, 0x001b, 0x0777, 0x3003, 10 },
295+ { ubnt, "XR4", 0x168c, 0x001b, 0x0777, 0x3004, 10 },
296+ { ubnt, "XR5", 0x168c, 0x001b, 0x0777, 0x3005, 10 },
297+ { ubnt, "XR5", 0x168c, 0x001b, 0x7777, 0x3005, 10 },
298+ { ubnt, "XR7", 0x168c, 0x001b, 0x0777, 0x3007, 10 },
299+ { ubnt, "XR9", 0x168c, 0x001b, 0x0777, 0x3009, 10 },
300+ { ubnt, "SRC", 0x168c, 0x0013, 0x168c, 0x1042, 1 },
301+ { ubnt, "SR2", 0x168c, 0x0013, 0x0777, 0x2041, 10 },
302+ { ubnt, "SR4", 0x168c, 0x0013, 0x0777, 0x2004, 6 },
303+ { ubnt, "SR4", 0x168c, 0x0013, 0x7777, 0x2004, 6 },
304+ { ubnt, "SR4C", 0x168c, 0x0013, 0x0777, 0x1004, 6 },
305+ { ubnt, "SR4C", 0x168c, 0x0013, 0x7777, 0x1004, 6 },
306+ { ubnt, "SR5", 0x168c, 0x0013, 0x168c, 0x2042, 7 },
307+ { ubnt, "SR9", 0x168c, 0x0013, 0x7777, 0x2009, 12 },
308+ { ubnt, "SR71A", 0x168c, 0x0027, 0x168c, 0x2082, 10 },
309+ { ubnt, "SR71", 0x168c, 0x0027, 0x0777, 0x4082, 10 },
310+};
311+
312 static int
313 ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
314 {
315@@ -257,6 +284,10 @@ ath_pci_probe(struct pci_dev *pdev, cons
316     printk(KERN_INFO "%s: %s: %s: mem=0x%lx, irq=%d\n",
317         dev_info, dev->name, athname ? athname : "Atheros ???", phymem, dev->irq);
318 
319+ ath_hw_detect(&sc->aps_sc, cards, ARRAY_SIZE(cards),
320+ pdev->vendor, pdev->device,
321+ pdev->subsystem_vendor, pdev->subsystem_device);
322+
323     /* ready to process interrupts */
324     sc->aps_sc.sc_invalid = 0;
325 
326

Archive Download this file



interactive