]> Git Repo - J-linux.git/blob - drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / drivers / net / ethernet / stmicro / stmmac / dwmac-ipq806x.c
1 /*
2  * Qualcomm Atheros IPQ806x GMAC glue layer
3  *
4  * Copyright (C) 2015 The Linux Foundation
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include <linux/device.h>
20 #include <linux/platform_device.h>
21 #include <linux/phy.h>
22 #include <linux/regmap.h>
23 #include <linux/clk.h>
24 #include <linux/reset.h>
25 #include <linux/of_net.h>
26 #include <linux/mfd/syscon.h>
27 #include <linux/stmmac.h>
28 #include <linux/of_mdio.h>
29 #include <linux/module.h>
30 #include <linux/sys_soc.h>
31 #include <linux/bitfield.h>
32
33 #include "stmmac_platform.h"
34
35 #define NSS_COMMON_CLK_GATE                     0x8
36 #define NSS_COMMON_CLK_GATE_PTP_EN(x)           BIT(0x10 + x)
37 #define NSS_COMMON_CLK_GATE_RGMII_RX_EN(x)      BIT(0x9 + (x * 2))
38 #define NSS_COMMON_CLK_GATE_RGMII_TX_EN(x)      BIT(0x8 + (x * 2))
39 #define NSS_COMMON_CLK_GATE_GMII_RX_EN(x)       BIT(0x4 + x)
40 #define NSS_COMMON_CLK_GATE_GMII_TX_EN(x)       BIT(0x0 + x)
41
42 #define NSS_COMMON_CLK_DIV0                     0xC
43 #define NSS_COMMON_CLK_DIV_OFFSET(x)            (x * 8)
44 #define NSS_COMMON_CLK_DIV_MASK                 0x7f
45
46 #define NSS_COMMON_CLK_SRC_CTRL                 0x14
47 #define NSS_COMMON_CLK_SRC_CTRL_OFFSET(x)       (x)
48 /* Mode is coded on 1 bit but is different depending on the MAC ID:
49  * MAC0: QSGMII=0 RGMII=1
50  * MAC1: QSGMII=0 SGMII=0 RGMII=1
51  * MAC2 & MAC3: QSGMII=0 SGMII=1
52  */
53 #define NSS_COMMON_CLK_SRC_CTRL_RGMII(x)        1
54 #define NSS_COMMON_CLK_SRC_CTRL_SGMII(x)        ((x >= 2) ? 1 : 0)
55
56 #define NSS_COMMON_GMAC_CTL(x)                  (0x30 + (x * 4))
57 #define NSS_COMMON_GMAC_CTL_CSYS_REQ            BIT(19)
58 #define NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL       BIT(16)
59 #define NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET    8
60 #define NSS_COMMON_GMAC_CTL_IFG_OFFSET          0
61
62 #define NSS_COMMON_CLK_DIV_RGMII_1000           1
63 #define NSS_COMMON_CLK_DIV_RGMII_100            9
64 #define NSS_COMMON_CLK_DIV_RGMII_10             99
65 #define NSS_COMMON_CLK_DIV_SGMII_1000           0
66 #define NSS_COMMON_CLK_DIV_SGMII_100            4
67 #define NSS_COMMON_CLK_DIV_SGMII_10             49
68
69 #define QSGMII_PCS_ALL_CH_CTL                   0x80
70 #define QSGMII_PCS_CH_SPEED_FORCE               BIT(1)
71 #define QSGMII_PCS_CH_SPEED_10                  0x0
72 #define QSGMII_PCS_CH_SPEED_100                 BIT(2)
73 #define QSGMII_PCS_CH_SPEED_1000                BIT(3)
74 #define QSGMII_PCS_CH_SPEED_MASK                (QSGMII_PCS_CH_SPEED_FORCE | \
75                                                  QSGMII_PCS_CH_SPEED_10 | \
76                                                  QSGMII_PCS_CH_SPEED_100 | \
77                                                  QSGMII_PCS_CH_SPEED_1000)
78 #define QSGMII_PCS_CH_SPEED_SHIFT(x)            ((x) * 4)
79
80 #define QSGMII_PCS_CAL_LCKDT_CTL                0x120
81 #define QSGMII_PCS_CAL_LCKDT_CTL_RST            BIT(19)
82
83 /* Only GMAC1/2/3 support SGMII and their CTL register are not contiguous */
84 #define QSGMII_PHY_SGMII_CTL(x)                 ((x == 1) ? 0x134 : \
85                                                  (0x13c + (4 * (x - 2))))
86 #define QSGMII_PHY_CDR_EN                       BIT(0)
87 #define QSGMII_PHY_RX_FRONT_EN                  BIT(1)
88 #define QSGMII_PHY_RX_SIGNAL_DETECT_EN          BIT(2)
89 #define QSGMII_PHY_TX_DRIVER_EN                 BIT(3)
90 #define QSGMII_PHY_QSGMII_EN                    BIT(7)
91 #define QSGMII_PHY_DEEMPHASIS_LVL_MASK          GENMASK(11, 10)
92 #define QSGMII_PHY_DEEMPHASIS_LVL(x)            FIELD_PREP(QSGMII_PHY_DEEMPHASIS_LVL_MASK, (x))
93 #define QSGMII_PHY_PHASE_LOOP_GAIN_MASK         GENMASK(14, 12)
94 #define QSGMII_PHY_PHASE_LOOP_GAIN(x)           FIELD_PREP(QSGMII_PHY_PHASE_LOOP_GAIN_MASK, (x))
95 #define QSGMII_PHY_RX_DC_BIAS_MASK              GENMASK(19, 18)
96 #define QSGMII_PHY_RX_DC_BIAS(x)                FIELD_PREP(QSGMII_PHY_RX_DC_BIAS_MASK, (x))
97 #define QSGMII_PHY_RX_INPUT_EQU_MASK            GENMASK(21, 20)
98 #define QSGMII_PHY_RX_INPUT_EQU(x)              FIELD_PREP(QSGMII_PHY_RX_INPUT_EQU_MASK, (x))
99 #define QSGMII_PHY_CDR_PI_SLEW_MASK             GENMASK(23, 22)
100 #define QSGMII_PHY_CDR_PI_SLEW(x)               FIELD_PREP(QSGMII_PHY_CDR_PI_SLEW_MASK, (x))
101 #define QSGMII_PHY_TX_SLEW_MASK                 GENMASK(27, 26)
102 #define QSGMII_PHY_TX_SLEW(x)                   FIELD_PREP(QSGMII_PHY_TX_SLEW_MASK, (x))
103 #define QSGMII_PHY_TX_DRV_AMP_MASK              GENMASK(31, 28)
104 #define QSGMII_PHY_TX_DRV_AMP(x)                FIELD_PREP(QSGMII_PHY_TX_DRV_AMP_MASK, (x))
105
106 struct ipq806x_gmac {
107         struct platform_device *pdev;
108         struct regmap *nss_common;
109         struct regmap *qsgmii_csr;
110         uint32_t id;
111         struct clk *core_clk;
112         phy_interface_t phy_mode;
113 };
114
115 static int get_clk_div_sgmii(struct ipq806x_gmac *gmac, unsigned int speed)
116 {
117         struct device *dev = &gmac->pdev->dev;
118         int div;
119
120         switch (speed) {
121         case SPEED_1000:
122                 div = NSS_COMMON_CLK_DIV_SGMII_1000;
123                 break;
124
125         case SPEED_100:
126                 div = NSS_COMMON_CLK_DIV_SGMII_100;
127                 break;
128
129         case SPEED_10:
130                 div = NSS_COMMON_CLK_DIV_SGMII_10;
131                 break;
132
133         default:
134                 dev_err(dev, "Speed %dMbps not supported in SGMII\n", speed);
135                 return -EINVAL;
136         }
137
138         return div;
139 }
140
141 static int get_clk_div_rgmii(struct ipq806x_gmac *gmac, unsigned int speed)
142 {
143         struct device *dev = &gmac->pdev->dev;
144         int div;
145
146         switch (speed) {
147         case SPEED_1000:
148                 div = NSS_COMMON_CLK_DIV_RGMII_1000;
149                 break;
150
151         case SPEED_100:
152                 div = NSS_COMMON_CLK_DIV_RGMII_100;
153                 break;
154
155         case SPEED_10:
156                 div = NSS_COMMON_CLK_DIV_RGMII_10;
157                 break;
158
159         default:
160                 dev_err(dev, "Speed %dMbps not supported in RGMII\n", speed);
161                 return -EINVAL;
162         }
163
164         return div;
165 }
166
167 static int ipq806x_gmac_set_speed(struct ipq806x_gmac *gmac, unsigned int speed)
168 {
169         uint32_t clk_bits, val;
170         int div;
171
172         switch (gmac->phy_mode) {
173         case PHY_INTERFACE_MODE_RGMII:
174         case PHY_INTERFACE_MODE_RGMII_ID:
175         case PHY_INTERFACE_MODE_RGMII_RXID:
176         case PHY_INTERFACE_MODE_RGMII_TXID:
177                 div = get_clk_div_rgmii(gmac, speed);
178                 clk_bits = NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
179                            NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
180                 break;
181
182         case PHY_INTERFACE_MODE_SGMII:
183                 div = get_clk_div_sgmii(gmac, speed);
184                 clk_bits = NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
185                            NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
186                 break;
187
188         default:
189                 dev_err(&gmac->pdev->dev, "Unsupported PHY mode: \"%s\"\n",
190                         phy_modes(gmac->phy_mode));
191                 return -EINVAL;
192         }
193
194         /* Disable the clocks */
195         regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
196         val &= ~clk_bits;
197         regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
198
199         /* Set the divider */
200         regmap_read(gmac->nss_common, NSS_COMMON_CLK_DIV0, &val);
201         val &= ~(NSS_COMMON_CLK_DIV_MASK
202                  << NSS_COMMON_CLK_DIV_OFFSET(gmac->id));
203         val |= div << NSS_COMMON_CLK_DIV_OFFSET(gmac->id);
204         regmap_write(gmac->nss_common, NSS_COMMON_CLK_DIV0, val);
205
206         /* Enable the clock back */
207         regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
208         val |= clk_bits;
209         regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
210
211         return 0;
212 }
213
214 static int ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac)
215 {
216         struct device *dev = &gmac->pdev->dev;
217         int ret;
218
219         ret = of_get_phy_mode(dev->of_node, &gmac->phy_mode);
220         if (ret) {
221                 dev_err(dev, "missing phy mode property\n");
222                 return -EINVAL;
223         }
224
225         if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) {
226                 dev_err(dev, "missing qcom id property\n");
227                 return -EINVAL;
228         }
229
230         /* The GMACs are called 1 to 4 in the documentation, but to simplify the
231          * code and keep it consistent with the Linux convention, we'll number
232          * them from 0 to 3 here.
233          */
234         if (gmac->id > 3) {
235                 dev_err(dev, "invalid gmac id\n");
236                 return -EINVAL;
237         }
238
239         gmac->core_clk = devm_clk_get(dev, "stmmaceth");
240         if (IS_ERR(gmac->core_clk)) {
241                 dev_err(dev, "missing stmmaceth clk property\n");
242                 return PTR_ERR(gmac->core_clk);
243         }
244         clk_set_rate(gmac->core_clk, 266000000);
245
246         /* Setup the register map for the nss common registers */
247         gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node,
248                                                            "qcom,nss-common");
249         if (IS_ERR(gmac->nss_common)) {
250                 dev_err(dev, "missing nss-common node\n");
251                 return PTR_ERR(gmac->nss_common);
252         }
253
254         /* Setup the register map for the qsgmii csr registers */
255         gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node,
256                                                            "qcom,qsgmii-csr");
257         if (IS_ERR(gmac->qsgmii_csr))
258                 dev_err(dev, "missing qsgmii-csr node\n");
259
260         return PTR_ERR_OR_ZERO(gmac->qsgmii_csr);
261 }
262
263 static void ipq806x_gmac_fix_mac_speed(void *priv, unsigned int speed, unsigned int mode)
264 {
265         struct ipq806x_gmac *gmac = priv;
266
267         ipq806x_gmac_set_speed(gmac, speed);
268 }
269
270 static int
271 ipq806x_gmac_configure_qsgmii_pcs_speed(struct ipq806x_gmac *gmac)
272 {
273         struct platform_device *pdev = gmac->pdev;
274         struct device *dev = &pdev->dev;
275         struct device_node *dn;
276         int link_speed;
277         int val = 0;
278         int ret;
279
280         /* Some bootloader may apply wrong configuration and cause
281          * not functioning port. If fixed link is not set,
282          * reset the force speed bit.
283          */
284         if (!of_phy_is_fixed_link(pdev->dev.of_node))
285                 goto write;
286
287         dn = of_get_child_by_name(pdev->dev.of_node, "fixed-link");
288         ret = of_property_read_u32(dn, "speed", &link_speed);
289         of_node_put(dn);
290         if (ret) {
291                 dev_err(dev, "found fixed-link node with no speed");
292                 return ret;
293         }
294
295         val = QSGMII_PCS_CH_SPEED_FORCE;
296
297         switch (link_speed) {
298         case SPEED_1000:
299                 val |= QSGMII_PCS_CH_SPEED_1000;
300                 break;
301         case SPEED_100:
302                 val |= QSGMII_PCS_CH_SPEED_100;
303                 break;
304         case SPEED_10:
305                 val |= QSGMII_PCS_CH_SPEED_10;
306                 break;
307         }
308
309 write:
310         regmap_update_bits(gmac->qsgmii_csr, QSGMII_PCS_ALL_CH_CTL,
311                            QSGMII_PCS_CH_SPEED_MASK <<
312                            QSGMII_PCS_CH_SPEED_SHIFT(gmac->id),
313                            val <<
314                            QSGMII_PCS_CH_SPEED_SHIFT(gmac->id));
315
316         return 0;
317 }
318
319 static const struct soc_device_attribute ipq806x_gmac_soc_v1[] = {
320         {
321                 .revision = "1.*",
322         },
323         {
324                 /* sentinel */
325         }
326 };
327
328 static int
329 ipq806x_gmac_configure_qsgmii_params(struct ipq806x_gmac *gmac)
330 {
331         struct platform_device *pdev = gmac->pdev;
332         const struct soc_device_attribute *soc;
333         struct device *dev = &pdev->dev;
334         u32 qsgmii_param;
335
336         switch (gmac->id) {
337         case 1:
338                 soc = soc_device_match(ipq806x_gmac_soc_v1);
339
340                 if (soc)
341                         qsgmii_param = QSGMII_PHY_TX_DRV_AMP(0xc) |
342                                        QSGMII_PHY_TX_SLEW(0x2) |
343                                        QSGMII_PHY_DEEMPHASIS_LVL(0x2);
344                 else
345                         qsgmii_param = QSGMII_PHY_TX_DRV_AMP(0xd) |
346                                        QSGMII_PHY_TX_SLEW(0x0) |
347                                        QSGMII_PHY_DEEMPHASIS_LVL(0x0);
348
349                 qsgmii_param |= QSGMII_PHY_RX_DC_BIAS(0x2);
350                 break;
351         case 2:
352         case 3:
353                 qsgmii_param = QSGMII_PHY_RX_DC_BIAS(0x3) |
354                                QSGMII_PHY_TX_DRV_AMP(0xc);
355                 break;
356         default: /* gmac 0 can't be set in SGMII mode */
357                 dev_err(dev, "gmac id %d can't be in SGMII mode", gmac->id);
358                 return -EINVAL;
359         }
360
361         /* Common params across all gmac id */
362         qsgmii_param |= QSGMII_PHY_CDR_EN |
363                         QSGMII_PHY_RX_FRONT_EN |
364                         QSGMII_PHY_RX_SIGNAL_DETECT_EN |
365                         QSGMII_PHY_TX_DRIVER_EN |
366                         QSGMII_PHY_QSGMII_EN |
367                         QSGMII_PHY_PHASE_LOOP_GAIN(0x4) |
368                         QSGMII_PHY_RX_INPUT_EQU(0x1) |
369                         QSGMII_PHY_CDR_PI_SLEW(0x2);
370
371         regmap_write(gmac->qsgmii_csr, QSGMII_PHY_SGMII_CTL(gmac->id),
372                      qsgmii_param);
373
374         return 0;
375 }
376
377 static int ipq806x_gmac_probe(struct platform_device *pdev)
378 {
379         struct plat_stmmacenet_data *plat_dat;
380         struct stmmac_resources stmmac_res;
381         struct device *dev = &pdev->dev;
382         struct ipq806x_gmac *gmac;
383         int val;
384         int err;
385
386         val = stmmac_get_platform_resources(pdev, &stmmac_res);
387         if (val)
388                 return val;
389
390         plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
391         if (IS_ERR(plat_dat))
392                 return PTR_ERR(plat_dat);
393
394         gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL);
395         if (!gmac)
396                 return -ENOMEM;
397
398         gmac->pdev = pdev;
399
400         err = ipq806x_gmac_of_parse(gmac);
401         if (err) {
402                 dev_err(dev, "device tree parsing error\n");
403                 return err;
404         }
405
406         regmap_write(gmac->qsgmii_csr, QSGMII_PCS_CAL_LCKDT_CTL,
407                      QSGMII_PCS_CAL_LCKDT_CTL_RST);
408
409         /* Inter frame gap is set to 12 */
410         val = 12 << NSS_COMMON_GMAC_CTL_IFG_OFFSET |
411               12 << NSS_COMMON_GMAC_CTL_IFG_LIMIT_OFFSET;
412         /* We also initiate an AXI low power exit request */
413         val |= NSS_COMMON_GMAC_CTL_CSYS_REQ;
414         switch (gmac->phy_mode) {
415         case PHY_INTERFACE_MODE_RGMII:
416         case PHY_INTERFACE_MODE_RGMII_ID:
417         case PHY_INTERFACE_MODE_RGMII_RXID:
418         case PHY_INTERFACE_MODE_RGMII_TXID:
419                 val |= NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
420                 break;
421         case PHY_INTERFACE_MODE_SGMII:
422                 val &= ~NSS_COMMON_GMAC_CTL_PHY_IFACE_SEL;
423                 break;
424         default:
425                 goto err_unsupported_phy;
426         }
427         regmap_write(gmac->nss_common, NSS_COMMON_GMAC_CTL(gmac->id), val);
428
429         /* Configure the clock src according to the mode */
430         regmap_read(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, &val);
431         val &= ~(1 << NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id));
432         switch (gmac->phy_mode) {
433         case PHY_INTERFACE_MODE_RGMII:
434         case PHY_INTERFACE_MODE_RGMII_ID:
435         case PHY_INTERFACE_MODE_RGMII_RXID:
436         case PHY_INTERFACE_MODE_RGMII_TXID:
437                 val |= NSS_COMMON_CLK_SRC_CTRL_RGMII(gmac->id) <<
438                         NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
439                 break;
440         case PHY_INTERFACE_MODE_SGMII:
441                 val |= NSS_COMMON_CLK_SRC_CTRL_SGMII(gmac->id) <<
442                         NSS_COMMON_CLK_SRC_CTRL_OFFSET(gmac->id);
443                 break;
444         default:
445                 goto err_unsupported_phy;
446         }
447         regmap_write(gmac->nss_common, NSS_COMMON_CLK_SRC_CTRL, val);
448
449         /* Enable PTP clock */
450         regmap_read(gmac->nss_common, NSS_COMMON_CLK_GATE, &val);
451         val |= NSS_COMMON_CLK_GATE_PTP_EN(gmac->id);
452         switch (gmac->phy_mode) {
453         case PHY_INTERFACE_MODE_RGMII:
454         case PHY_INTERFACE_MODE_RGMII_ID:
455         case PHY_INTERFACE_MODE_RGMII_RXID:
456         case PHY_INTERFACE_MODE_RGMII_TXID:
457                 val |= NSS_COMMON_CLK_GATE_RGMII_RX_EN(gmac->id) |
458                         NSS_COMMON_CLK_GATE_RGMII_TX_EN(gmac->id);
459                 break;
460         case PHY_INTERFACE_MODE_SGMII:
461                 val |= NSS_COMMON_CLK_GATE_GMII_RX_EN(gmac->id) |
462                                 NSS_COMMON_CLK_GATE_GMII_TX_EN(gmac->id);
463                 break;
464         default:
465                 goto err_unsupported_phy;
466         }
467         regmap_write(gmac->nss_common, NSS_COMMON_CLK_GATE, val);
468
469         if (gmac->phy_mode == PHY_INTERFACE_MODE_SGMII) {
470                 err = ipq806x_gmac_configure_qsgmii_params(gmac);
471                 if (err)
472                         return err;
473
474                 err = ipq806x_gmac_configure_qsgmii_pcs_speed(gmac);
475                 if (err)
476                         return err;
477         }
478
479         plat_dat->has_gmac = true;
480         plat_dat->bsp_priv = gmac;
481         plat_dat->fix_mac_speed = ipq806x_gmac_fix_mac_speed;
482         plat_dat->multicast_filter_bins = 0;
483         plat_dat->tx_fifo_size = 8192;
484         plat_dat->rx_fifo_size = 8192;
485
486         return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
487
488 err_unsupported_phy:
489         dev_err(&pdev->dev, "Unsupported PHY mode: \"%s\"\n",
490                 phy_modes(gmac->phy_mode));
491         return -EINVAL;
492 }
493
494 static const struct of_device_id ipq806x_gmac_dwmac_match[] = {
495         { .compatible = "qcom,ipq806x-gmac" },
496         { }
497 };
498 MODULE_DEVICE_TABLE(of, ipq806x_gmac_dwmac_match);
499
500 static struct platform_driver ipq806x_gmac_dwmac_driver = {
501         .probe = ipq806x_gmac_probe,
502         .remove = stmmac_pltfr_remove,
503         .driver = {
504                 .name           = "ipq806x-gmac-dwmac",
505                 .pm             = &stmmac_pltfr_pm_ops,
506                 .of_match_table = ipq806x_gmac_dwmac_match,
507         },
508 };
509 module_platform_driver(ipq806x_gmac_dwmac_driver);
510
511 MODULE_AUTHOR("Mathieu Olivari <[email protected]>");
512 MODULE_DESCRIPTION("Qualcomm Atheros IPQ806x DWMAC specific glue layer");
513 MODULE_LICENSE("Dual BSD/GPL");
This page took 0.057352 seconds and 4 git commands to generate.