guowenxue
2024-06-02 eaa90c75a6b4981dbbb15e3ebf851c056bf015c9
commit | author | age
435024 1 diff --git a/Makefile b/Makefile
G 2 index 4c06cbe89..3dbf9430a 100644
3 --- a/Makefile
4 +++ b/Makefile
5 @@ -383,6 +383,9 @@ include $(srctree)/scripts/subarch.include
6  # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
7  ARCH        ?= $(SUBARCH)
8  
9 +ARCH = arm64
10 +CROSS_COMPILE ?= aarch64-linux-gnu-
11 +
12  # Architecture as present in compile.h
13  UTS_MACHINE     := $(ARCH)
14  SRCARCH     := $(ARCH)
15 diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
16 index 9a7319c6b..23cb09c85 100644
17 --- a/arch/arm64/boot/dts/freescale/Makefile
18 +++ b/arch/arm64/boot/dts/freescale/Makefile
19 @@ -119,6 +119,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk.dtb
20  dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb imx8mq-evk-rpmsg.dtb imx8mp-ab2.dtb
21  dtb-$(CONFIG_ARCH_MXC) += imx8mp-ddr4-evk.dtb
22  dtb-$(CONFIG_ARCH_MXC) += imx8mp-evk-ndm.dtb
23 +dtb-$(CONFIG_ARCH_MXC) += gauguin-imx8mp.dtb
24  dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb imx8mq-evk-rpmsg.dtb imx8mq-evk-pcie1-m2.dtb imx8mq-evk-usd-wifi.dtb \
25                imx8mq-evk-usdhc2-m2.dtb
26  dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk-ak4497.dtb imx8mq-evk-audio-tdm.dtb imx8mq-evk-pdm.dtb
27 diff --git a/arch/arm64/boot/dts/freescale/gauguin-imx8mp.dts b/arch/arm64/boot/dts/freescale/gauguin-imx8mp.dts
28 new file mode 100644
29 index 000000000..f48c97c78
30 --- /dev/null
31 +++ b/arch/arm64/boot/dts/freescale/gauguin-imx8mp.dts
32 @@ -0,0 +1,1000 @@
33 +/*
34 + * Device Tree Source for ZhiTu GauGuin Board - i.MX8MP 
35 + * Based on imx8mp-evk.dts/imx8mp-evk.dtsi
36 + *
37 + * Copyright (C) 2023 LingYun IoT System Studio.
38 + * Author: Guo Wenxue<guowenxue@gmail.com>
39 + */
40 +
41 +/dts-v1/;
42 +
43 +#include <dt-bindings/usb/pd.h>
44 +#include "imx8mp.dtsi"
45 +
46 +// #define SIMPLE_CARD /*simple_card support */
47 +
48 +/ {
49 +    model = "ZhiTu GauGuin Board - i.MX8MP";
50 +    compatible = "fsl,imx8mp-evk", "fsl,imx8mp";
51 +
52 +    chosen {
53 +        stdout-path = &uart2;
54 +    };
55 +
56 +    gpio-devs-ctrl {
57 +        compatible = "gpio-leds";
58 +        pinctrl-names = "devs-group";
59 +        pinctrl-0 = <&pinctrl_gpio_devs_group>;
60 +
61 +        uart-switch {
62 +            label = "uart-switch";
63 +            gpios = <&gpio4 27 GPIO_ACTIVE_HIGH>;
64 +            default-state = "on";
65 +        };
66 +
67 +        usb1-vbus {
68 +            label = "usb1-vbus-en";
69 +            gpios = <&gpio4 25 GPIO_ACTIVE_HIGH>;
70 +            default-state = "on";
71 +        };
72 +
73 +        wwan-power-on {
74 +            label = "wwan-power-on";
75 +            gpios = <&gpio2 16 GPIO_ACTIVE_LOW>;
76 +            default-state = "on";
77 +        };
78 +
79 +        wwan-reset {
80 +            label = "wwan-reset";
81 +            gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
82 +            default-state = "on";
83 +        };
84 +    };
85 +
86 +    gpio-leds {
87 +        compatible = "gpio-leds";
88 +        pinctrl-names = "default";
89 +        pinctrl-0 = <&pinctrl_gpio_leds_group>;
90 +
91 +        sys-status {
92 +            label = "sys-status";
93 +            gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>;
94 +            // linux,default-trigger = "heartbeat";
95 +            default-state = "on";
96 +        };
97 +
98 +        rgb-led-red {
99 +            label = "red";
100 +            gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
101 +            default-state = "on";
102 +        };
103 +
104 +        rgb-led-green {
105 +            label = "green";
106 +            gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
107 +            default-state = "off";
108 +        };
109 +
110 +        rgb-led-blue {
111 +            label = "blue";
112 +            gpios = <&gpio2 17 GPIO_ACTIVE_HIGH>;
113 +            default-state = "off";
114 +        };        
115 +        
116 +        rgb-led-ext-red {
117 +            label = "ext-red";
118 +            gpios = <&gpio3 25 GPIO_ACTIVE_HIGH>;
119 +            default-state = "on";
120 +        };
121 +
122 +        rgb-led-ext-green {
123 +            label = "ext-green";
124 +            gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>;
125 +            default-state = "on";
126 +        };
127 +
128 +        rgb-led-ext-blue {
129 +            label = "ext-blue";
130 +            gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
131 +            default-state = "on";
132 +        };
133 +    };
134 +
135 +    memory@40000000 {
136 +        device_type = "memory";
137 +        reg = <0x0 0x40000000 0 0xc0000000>,
138 +              <0x1 0x00000000 0 0xc0000000>;
139 +    };
140 +    /*+--------------+
141 +        |   Regulator  |
142 +        +--------------+*/
143 +    /*4G power_en # low-->en*/
144 +    regulator-wwan-prower-en {
145 +        compatible = "regulator-fixed";
146 +        regulator-name = "wwan-prower-en";
147 +        pinctrl-names = "default";
148 +        pinctrl-0 = <&pinctrl_wwan_reg>;
149 +        regulator-min-microvolt = <3300000>;
150 +        regulator-max-microvolt = <3300000>;
151 +        gpios = <&gpio5 10 GPIO_ACTIVE_LOW>;
152 +        enable-active-low;
153 +        regulator-always-on;
154 +    };
155 +
156 +    /*usb host vbus en # low-->en*/
157 +    regulator-usb-host-vbus-en {
158 +        compatible = "regulator-fixed";
159 +        regulator-name = "usb-host-vbus-en";
160 +        pinctrl-names = "default";
161 +        pinctrl-0 = <&pinctrl_usb_host_reg>;
162 +        regulator-min-microvolt = <3300000>;
163 +        regulator-max-microvolt = <3300000>;
164 +        gpios = <&gpio5 12 GPIO_ACTIVE_LOW>;
165 +        enable-active-low;
166 +        regulator-always-on;
167 +    };
168 +
169 +    /*lcd reset : 硬件已经拉高*/
170 +    regulator-lcd-reset {
171 +        compatible = "regulator-fixed";
172 +        regulator-name = "lcd-reset";
173 +        regulator-min-microvolt = <3300000>;
174 +        regulator-max-microvolt = <3300000>;
175 +        gpios = <&gpio5 7 GPIO_ACTIVE_HIGH>;
176 +        enable-active-high;
177 +        regulator-boot-on;
178 +        regulator-always-on;
179 +    };
180 +    /delete-node/ regulator-lcd-reset;
181 +
182 +    /*audio ap shotdown low-->en*/
183 +    reg_audio_pwr: regulator-audio-pwr {
184 +        compatible = "regulator-fixed";
185 +        regulator-name = "audio-pwr";
186 +        regulator-min-microvolt = <3300000>;
187 +        regulator-max-microvolt = <3300000>;
188 +        gpios = <&gpio4 28 GPIO_ACTIVE_LOW>;
189 +        enable-active-low;
190 +        regulator-always-on;
191 +    };
192 +
193 +    /*+---------------+
194 +        |   Sound Card  |
195 +        +--------------+*/
196 +#ifndef SIMPLE_CARD
197 +    sound-nau8822 {
198 +        compatible = "fsl,imx-audio-nau8822"; 
199 +        model = "nau8822-audio";/*声卡名字*/
200 +        audio-cpu = <&sai3>; /*cpu-dai*/
201 +        audio-codec = <&codec>;/*codec-dai*/
202 +        audio-asrc = <&easrc>; /*增强型异步采样器*/
203 +        audio-routing =    //sink + source 需使用 源码已有的组件
204 +            "Headphone Jack", "LHP",
205 +            "Headphone Jack", "RHP",
206 +            "Ext Spk", "LSPK",
207 +            "Ext Spk", "RSPK",
208 +            "Line Out Jack", "AUXOUT1",
209 +            "Line Out Jack", "AUXOUT2",
210 +            "LAUX", "Line In Jack",
211 +            "RAUX", "Line In Jack",
212 +            "LMICN", "Mic Jack",
213 +            "LMICP", "Mic Jack",
214 +            "RMICN", "Mic Jack",
215 +            "RMICP", "Mic Jack";
216 +    };
217 +#else
218 +    sound_card: sound-card 
219 +    {
220 +        compatible = "simple-audio-card";
221 +        simple-audio-card,bitclock-master = <&dailink_master>;/*master 时钟 */
222 +        simple-audio-card,format = "i2s";/*传输格式*/
223 +        simple-audio-card,frame-master = <&dailink_master>;/*master 帧*/
224 +        simple-audio-card,name = "imx8mp-nau8822"; /*aplay -l 出现的声卡名字*/
225 +        simple-audio-card,widgets =    /*声卡组件 board组件*/
226 +            "Headphones", "Headphones",
227 +            "Line Out", "Line Out",
228 +            "Speaker", "Speaker",
229 +            "Microphone", "Mic In",
230 +            "Line", "Line In";
231 +        simple-audio-card,routing =    /*音频路由 sink + source*/
232 +            "Headphones", "LHP",
233 +            "Headphones", "RHP",
234 +            "Speaker", "LSPK",
235 +            "Speaker", "RSPK",
236 +            "Line Out", "AUXOUT1",
237 +            "Line Out", "AUXOUT2",
238 +            "LAUX", "Line In",
239 +            "RAUX", "Line In",
240 +            "LMICP",    "Mic In",
241 +            "RMICP",    "Mic In";
242 +        dailink_master: simple-audio-card,codec {/* 确定codec-dai */
243 +            sound-dai = <&codec>;
244 +            clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>; /*mclk 时钟*/
245 +        };
246 +
247 +        simple-audio-card,cpu {/* 确定cpu-dai */
248 +            sound-dai = <&sai3>; /*cpu dai*/
249 +        };
250 +    };
251 +#endif
252 +
253 +    // sound-xcvr { //音频收发器
254 +    //     compatible = "fsl,imx-audio-card";
255 +    //     model = "imx-audio-xcvr";
256 +    //     pri-dai-link {
257 +    //         link-name = "XCVR PCM";
258 +    //         cpu {
259 +    //             sound-dai = <&xcvr>;
260 +    //         };
261 +    //     };
262 +    // };
263 +
264 +    /*+---------------+
265 +        |   Lvds Panel  |
266 +        +--------------+*/
267 +    lvds0_panel {
268 +        compatible = "auo,g101ean02";
269 +        backlight = <&lvds_backlight>;
270 +        status = "okay";
271 +
272 +        port {
273 +            panel_lvds_in: endpoint {
274 +                remote-endpoint = <&lvds_out>;
275 +            };
276 +        };
277 +    };
278 +
279 +    lvds_backlight: lvds_backlight {
280 +        compatible = "pwm-backlight";
281 +        pwms = <&pwm2 0 100000>;
282 +        pinctrl-names = "default";
283 +        pinctrl-0 = <&pinctrl_backlight>;
284 +        enable-gpios = <&gpio5 6 GPIO_ACTIVE_LOW>;
285 +        status = "okay";
286 +
287 +        brightness-levels = < 0  1  2  3  4  5  6  7  8  9
288 +                            10 11 12 13 14 15 16 17 18 19
289 +                            20 21 22 23 24 25 26 27 28 29
290 +                            30 31 32 33 34 35 36 37 38 39
291 +                            40 41 42 43 44 45 46 47 48 49
292 +                            50 51 52 53 54 55 56 57 58 59
293 +                            60 61 62 63 64 65 66 67 68 69
294 +                            70 71 72 73 74 75 76 77 78 79
295 +                            80 81 82 83 84 85 86 87 88 89
296 +                            90 91 92 93 94 95 96 97 98 99
297 +                            100 >;
298 +        default-brightness-level = <20>;
299 +    };
300 +
301 +    /*+---------------+
302 +        |  Extcon gpio  |
303 +        +--------------+*/
304 +    extcon_dwc3: extcon_dwc3 {
305 +        compatible = "linux,extcon-usb-gpio";
306 +        pinctrl-names = "default";
307 +        pinctrl-0 = <&pinctrl_usb0_id_grp>;
308 +        id-gpio = <&gpio4 26 GPIO_ACTIVE_HIGH>;
309 +    };
310 +};
311 +
312 +/*+--------------+
313 +  | Misc Modules |
314 +  +--------------+*/
315 +&snvs_pwrkey {
316 +    status = "okay";
317 +};
318 +
319 +&sdma2 {
320 +    status = "okay";
321 +};
322 +
323 +&pwm2 {
324 +    pinctrl-names = "default";
325 +    pinctrl-0 = <&pinctrl_pwm2>;
326 +    status = "okay";
327 +};
328 +
329 +&A53_0 {
330 +    cpu-supply = <&buck2>;
331 +};
332 +
333 +&A53_1 {
334 +    cpu-supply = <&buck2>;
335 +};
336 +
337 +&A53_2 {
338 +    cpu-supply = <&buck2>;
339 +};
340 +
341 +&A53_3 {
342 +    cpu-supply = <&buck2>;
343 +};
344 +
345 +&wdog1 {
346 +    pinctrl-names = "default";
347 +    pinctrl-0 = <&pinctrl_wdog>;
348 +    fsl,ext-reset-output;
349 +    status = "okay";
350 +};
351 +
352 +/*+------------------------+
353 +  | Uart and can interface |
354 +  +------------------------+*/
355 +&uart1 { 
356 +    /* RS485 */
357 +    pinctrl-names = "default";
358 +    pinctrl-0 = <&pinctrl_uart1>;
359 +    status = "okay";
360 +};
361 +
362 +&uart2 {
363 +    /* console */
364 +    pinctrl-names = "default";
365 +    pinctrl-0 = <&pinctrl_uart2>;
366 +    status = "okay";
367 +};
368 +
369 +&flexcan1 {
370 +    pinctrl-names = "default";
371 +    pinctrl-0 = <&pinctrl_flexcan1>;
372 +    status = "okay";
373 +};
374 +
375 +/*+--------------+
376 +  | Lvds Modules |
377 +  +--------------+*/
378 +&lcdif2 {
379 +    status = "okay";
380 +};
381 +
382 +&ldb {
383 +    status = "okay";
384 +
385 +    lvds-channel@0 {
386 +        fsl,data-mapping = "spwg";
387 +        fsl,data-width = <24>;
388 +        status = "okay";
389 +
390 +        port@1 {
391 +            reg = <1>;
392 +
393 +            lvds_out: endpoint {
394 +                remote-endpoint = <&panel_lvds_in>;
395 +            };
396 +        };
397 +    };
398 +};
399 +
400 +&ldb_phy {
401 +    status = "okay";
402 +};
403 +
404 +/*+--------------+
405 +  | Spi Modules |
406 +  +--------------+*/
407 +&flexspi {
408 +    pinctrl-names = "default";
409 +    pinctrl-0 = <&pinctrl_flexspi0>;
410 +    status = "okay";
411 +
412 +    flash0: mt25qu256aba@0 {
413 +        reg = <0>;
414 +        #address-cells = <1>;
415 +        #size-cells = <1>;
416 +        compatible = "jedec,spi-nor";
417 +        spi-max-frequency = <80000000>;
418 +        spi-tx-bus-width = <1>;
419 +        spi-rx-bus-width = <4>;
420 +    };
421 +};
422 +
423 +/*+------------------+
424 +  | Ethernet Modules |
425 +  +------------------+*/
426 +&eqos { //T1 eth1
427 +    pinctrl-names = "default";
428 +    pinctrl-0 = <&pinctrl_eqos>;
429 +    phy-mode = "rgmii-id";
430 +    phy-handle = <&ethphy1>;
431 +    // snps,force_thresh_dma_mode;
432 +    // snps,mtl-tx-config = <&mtl_tx_setup>; /*TODO: dma相关*/
433 +    // snps,mtl-rx-config = <&mtl_rx_setup>;
434 +    status = "okay";
435 +
436 +    mdio {
437 +        compatible = "snps,dwmac-mdio";
438 +        #address-cells = <1>;
439 +        #size-cells = <0>;
440 +
441 +        ethphy1: ethernet-phy@1 {
442 +            compatible = "ethernet-phy-ieee802.3-c22";
443 +            reg = <1>;
444 +            eee-broken-1000t;
445 +            realtek,clkout-disable;
446 +        };
447 +    };
448 +};
449 +
450 +&fec {//T2 eth0
451 +    pinctrl-names = "default";
452 +    pinctrl-0 = <&pinctrl_fec>;
453 +    phy-mode = "rgmii-id";
454 +    phy-handle = <&ethphy2>;
455 +    fsl,magic-packet;
456 +    status = "okay";
457 +
458 +    mdio {
459 +        #address-cells = <1>;
460 +        #size-cells = <0>;
461 +
462 +        ethphy2: ethernet-phy@2 {
463 +            compatible = "ethernet-phy-ieee802.3-c22";
464 +            reg = <2>;
465 +            eee-broken-1000t;
466 +            reset-gpios = <&gpio4 2 GPIO_ACTIVE_LOW>;
467 +            reset-assert-us = <10000>;
468 +            reset-deassert-us = <80000>;
469 +            realtek,clkout-disable;
470 +        };
471 +    };
472 +};
473 +
474 +/*+---------------+
475 +  |   I2C Module  |
476 +  +---------------+*/
477 +&i2c1 {
478 +    clock-frequency = <400000>;
479 +    pinctrl-names = "default";
480 +    pinctrl-0 = <&pinctrl_i2c1>;
481 +    status = "okay";
482 +
483 +    pmic@25 {
484 +        compatible = "nxp,pca9450c";
485 +        reg = <0x25>;
486 +        pinctrl-names = "default";
487 +        pinctrl-0 = <&pinctrl_pmic>;
488 +        interrupt-parent = <&gpio1>;
489 +        interrupts = <3 IRQ_TYPE_LEVEL_LOW>;
490 +
491 +        regulators {
492 +            buck1: BUCK1 {
493 +                regulator-name = "BUCK1";
494 +                regulator-min-microvolt = <600000>;
495 +                regulator-max-microvolt = <2187500>;
496 +                regulator-boot-on;
497 +                regulator-always-on;
498 +                regulator-ramp-delay = <3125>;
499 +            };
500 +
501 +            buck2: BUCK2 {
502 +                regulator-name = "BUCK2";
503 +                regulator-min-microvolt = <600000>;
504 +                regulator-max-microvolt = <2187500>;
505 +                regulator-boot-on;
506 +                regulator-always-on;
507 +                regulator-ramp-delay = <3125>;
508 +                nxp,dvs-run-voltage = <950000>;
509 +                nxp,dvs-standby-voltage = <850000>;
510 +            };
511 +
512 +            buck4: BUCK4{
513 +                regulator-name = "BUCK4";
514 +                regulator-min-microvolt = <600000>;
515 +                regulator-max-microvolt = <3400000>;
516 +                regulator-boot-on;
517 +                regulator-always-on;
518 +            };
519 +
520 +            buck5: BUCK5{
521 +                regulator-name = "BUCK5";
522 +                regulator-min-microvolt = <600000>;
523 +                regulator-max-microvolt = <3400000>;
524 +                regulator-boot-on;
525 +                regulator-always-on;
526 +            };
527 +
528 +            buck6: BUCK6 {
529 +                regulator-name = "BUCK6";
530 +                regulator-min-microvolt = <600000>;
531 +                regulator-max-microvolt = <3400000>;
532 +                regulator-boot-on;
533 +                regulator-always-on;
534 +            };
535 +
536 +            ldo1: LDO1 {
537 +                regulator-name = "LDO1";
538 +                regulator-min-microvolt = <1600000>;
539 +                regulator-max-microvolt = <3300000>;
540 +                regulator-boot-on;
541 +                regulator-always-on;
542 +            };
543 +
544 +            ldo2: LDO2 {
545 +                regulator-name = "LDO2";
546 +                regulator-min-microvolt = <800000>;
547 +                regulator-max-microvolt = <1150000>;
548 +                regulator-boot-on;
549 +                regulator-always-on;
550 +            };
551 +
552 +            ldo3: LDO3 {
553 +                regulator-name = "LDO3";
554 +                regulator-min-microvolt = <800000>;
555 +                regulator-max-microvolt = <3300000>;
556 +                regulator-boot-on;
557 +                regulator-always-on;
558 +            };
559 +
560 +            ldo4: LDO4 {
561 +                regulator-name = "LDO4";
562 +                regulator-min-microvolt = <800000>;
563 +                regulator-max-microvolt = <3300000>;
564 +                regulator-boot-on;
565 +                regulator-always-on;
566 +            };
567 +
568 +            ldo5: LDO5 {
569 +                regulator-name = "LDO5";
570 +                regulator-min-microvolt = <1800000>;
571 +                regulator-max-microvolt = <3300000>;
572 +                regulator-boot-on;
573 +                regulator-always-on;
574 +            };
575 +        };
576 +    };
577 +};
578 +
579 +&i2c2 {
580 +    clock-frequency = <100000>;
581 +    pinctrl-names = "default";
582 +    pinctrl-0 = <&pinctrl_i2c2>;
583 +    status = "okay";
584 +
585 +    gt9xx@5d {
586 +        compatible = "goodix,gt928";
587 +        reg = <0x5d>;
588 +        pinctrl-names = "default";
589 +        pinctrl-0 = <&pinctrl_ts_pins>;
590 +
591 +        reset-gpios = <&gpio5 8 GPIO_ACTIVE_HIGH>;
592 +        irq-gpios = <&gpio5 9 GPIO_ACTIVE_HIGH>;
593 +        interrupt-parent = <&gpio5>;
594 +        interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
595 +
596 +        status = "okay"; /* Enable in LCD overlay */
597 +    };
598 +};
599 +
600 +&i2c3 {
601 +    clock-frequency = <400000>;
602 +    pinctrl-names = "default";
603 +    pinctrl-0 = <&pinctrl_i2c3>;
604 +    status = "okay";
605 +#ifndef SIMPLE_CARD
606 +    codec: nau8822@1a {
607 +        compatible = "nuvoton,nau8822";
608 +        reg = <0x1a>;
609 +        clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIO_BLK_CTRL_SAI3_MCLK1>; /*mclk时钟*/
610 +        clock-names = "mclk";
611 +    };
612 +#else
613 +    codec: nau8822@1a {
614 +        compatible = "nuvoton,nau8822";
615 +        reg = <0x1a>;
616 +        #sound-dai-cells = <0>;
617 +    };
618 +#endif
619 +};
620 +
621 +/*+--------------+
622 +  | Audio Module |
623 +  +--------------+*/
624 +&dsp {
625 +    status = "okay";
626 +};
627 +
628 +&aud2htx {
629 +    status = "okay";
630 +};
631 +
632 +&easrc {
633 +    fsl,asrc-rate  = <48000>;
634 +    status = "okay";
635 +};
636 +#ifndef SIMPLE_CARD
637 +&sai3 {
638 +    #sound-dai-cells = <0>;
639 +    pinctrl-names = "default";
640 +    pinctrl-0 = <&pinctrl_sai3>;
641 +    assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
642 +    assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
643 +    assigned-clock-rates = <12288000>;
644 +    fsl,sai-mclk-direction-output;
645 +    status = "okay";
646 +};
647 +#else
648 +&sai3 {
649 +    #sound-dai-cells = <0>;
650 +    pinctrl-names = "default";
651 +    pinctrl-0 = <&pinctrl_sai3>;
652 +    assigned-clocks = <&clk IMX8MP_CLK_SAI3>;
653 +    assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL1_OUT>;
654 +    // assigned-clock-rates = <24576000>;
655 +    assigned-clock-rates = <12288000>; /*48000*256 是 44100 * 2 * 16 的 2^n 倍数*/
656 +    fsl,sai-mclk-direction-output;
657 +    status = "okay";
658 +};
659 +#endif
660 +
661 +// &xcvr {
662 +//     #sound-dai-cells = <0>;
663 +//     status = "okay";
664 +// };
665 +
666 +/*+---------------+
667 +  | USB interface |
668 +  +---------------+*/
669 +//USB1
670 +&usb3_phy0 {
671 +    fsl,phy-tx-vref-tune = <0xe>;
672 +    fsl,phy-tx-preemp-amp-tune = <3>;
673 +    fsl,phy-tx-vboost-level = <5>;
674 +    fsl,phy-comp-dis-tune = <7>;
675 +    fsl,pcs-tx-deemph-3p5db = <0x21>;
676 +    fsl,phy-pcs-tx-swing-full = <0x7f>;
677 +    status = "okay";
678 +};
679 +
680 +&usb3_0 {
681 +    status = "okay";
682 +};
683 +
684 +#if 0
685 +&usb_dwc3_0 {
686 +    dr_mode = "host";//应该otg,TODO:otg id未解决
687 +    hnp-disable;
688 +    srp-disable;
689 +    adp-disable;
690 +    snps,usb2-lpm-disable;
691 +    // usb-role-switch;
692 +    // role-switch-default-mode = "none";
693 +    // snps,dis-u1-entry-quirk;
694 +    // snps,dis-u2-entry-quirk;
695 +    pinctrl-names = "default";
696 +    pinctrl-0 = <&pinctrl_usb0_id_grp>;
697 +    // interrupts = <&gpio4 26 IRQ_TYPE_EDGE_BOTH>,
698 +    //                 <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;// interrupt 需增加修改
699 +    // interrupt-names = "otg","";
700 +    power-polarity-active-high;//
701 +    disable-over-current;//
702 +    status = "okay";
703 +};
704 +#else
705 +&usb_dwc3_0 {
706 +    dr_mode = "otg";
707 +    hnp-disable;
708 +    srp-disable;
709 +    adp-disable;
710 +    status = "okay";
711 +    extcon = <&extcon_dwc3>;
712 +};
713 +#endif
714 +
715 +/* USB2 for 4G  or 5G module*/
716 +&usb3_phy1 {
717 +    fsl,phy-tx-preemp-amp-tune = <3>;
718 +    fsl,phy-tx-vref-tune = <0xb>;
719 +    status = "okay";
720 +};
721 +
722 +&usb3_1 {
723 +    status = "okay";
724 +};
725 +
726 +&usb_dwc3_1 {
727 +    dr_mode = "host";
728 +    status = "okay";
729 +};
730 +
731 +/*+------------------+
732 +  | USDCHC interface |
733 +  +------------------+*/
734 +&usdhc3 {
735 +    assigned-clocks = <&clk IMX8MP_CLK_USDHC3>;
736 +    assigned-clock-rates = <400000000>;
737 +    pinctrl-names = "default", "state_100mhz", "state_200mhz";
738 +    pinctrl-0 = <&pinctrl_usdhc3>;
739 +    pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
740 +    pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
741 +    bus-width = <8>;
742 +    non-removable;
743 +    status = "okay";
744 +};
745 +
746 +/*+----------------------+
747 +  | Basic pinctrl iomuxc |
748 +  +----------------------+*/
749 +&iomuxc {
750 +    pinctrl-names = "default";
751 +
752 +    pinctrl_backlight: backlightgrp {
753 +        fsl,pins = <
754 +            MX8MP_IOMUXC_ECSPI1_SCLK__GPIO5_IO06    0x19
755 +        >;
756 +    };
757 +
758 +    pinctrl_ts_pins: tsgrp {
759 +        fsl,pins = <
760 +            MX8MP_IOMUXC_ECSPI1_MISO__GPIO5_IO08    0x17059 /* TouchScreen RST */
761 +            MX8MP_IOMUXC_ECSPI1_SS0__GPIO5_IO09        0x17059 /* TouchScreen IRQ */
762 +        >;
763 +    };
764 +
765 +    pinctrl_pwm2: pwm2grp {
766 +        fsl,pins = <
767 +            MX8MP_IOMUXC_GPIO1_IO11__PWM2_OUT    0x116
768 +        >;
769 +    };
770 +
771 +    pinctrl_eqos: eqosgrp { //T1 TODO: 和evk不一致
772 +        fsl,pins = <
773 +            MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC                0x3
774 +            MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO                0x3
775 +            MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0            0x91
776 +            MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1            0x91
777 +            MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2            0x91
778 +            MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3            0x91
779 +            MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK    0x91
780 +            MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL            0x91
781 +            MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0            0x1f
782 +            MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1            0x1f
783 +            MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2            0x1f
784 +            MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3            0x1f
785 +            MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL            0x1f
786 +            MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK    0x1f
787 +            MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22                0x19
788 +        >;
789 +    };
790 +
791 +    pinctrl_fec: fecgrp {
792 +        fsl,pins = <
793 +            MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC        0x3
794 +            MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO        0x3
795 +            MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0        0x91
796 +            MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1        0x91
797 +            MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2        0x91
798 +            MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3        0x91
799 +            MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC        0x91
800 +            MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL    0x91
801 +            MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0        0x1f
802 +            MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1        0x1f
803 +            MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2        0x1f
804 +            MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3        0x1f
805 +            MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL    0x1f
806 +            MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC        0x1f
807 +            MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02        0x19
808 +        >;
809 +    };
810 +
811 +    pinctrl_flexspi0: flexspi0grp {
812 +        fsl,pins = <
813 +            MX8MP_IOMUXC_NAND_ALE__FLEXSPI_A_SCLK           0x1c2
814 +            MX8MP_IOMUXC_NAND_CE0_B__FLEXSPI_A_SS0_B        0x82
815 +            MX8MP_IOMUXC_NAND_DATA00__FLEXSPI_A_DATA00      0x82
816 +            MX8MP_IOMUXC_NAND_DATA01__FLEXSPI_A_DATA01      0x82
817 +            MX8MP_IOMUXC_NAND_DATA02__FLEXSPI_A_DATA02      0x82
818 +            MX8MP_IOMUXC_NAND_DATA03__FLEXSPI_A_DATA03      0x82
819 +        >;
820 +    };
821 +
822 +    pinctrl_flexcan1: flexcan1grp {
823 +        fsl,pins = <
824 +            MX8MP_IOMUXC_SPDIF_RX__CAN1_RX          0x154
825 +            MX8MP_IOMUXC_SPDIF_TX__CAN1_TX          0x154
826 +        >;
827 +    };
828 +
829 +    pinctrl_gpio_leds_group: gpioledsgrp {
830 +        fsl,pins = <
831 +            MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16    0x140
832 +            MX8MP_IOMUXC_SD1_STROBE__GPIO2_IO11        0x140
833 +            MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10    0x140
834 +            MX8MP_IOMUXC_SD2_DATA2__GPIO2_IO17        0x140
835 +            MX8MP_IOMUXC_SAI5_MCLK__GPIO3_IO25        0x140
836 +            MX8MP_IOMUXC_SAI5_RXFS__GPIO3_IO19        0x140
837 +        >;
838 +    };
839 +
840 +    pinctrl_gpio_devs_group: gpiodevsgrp {
841 +        fsl,pins = <
842 +            MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27        0x140
843 +            MX8MP_IOMUXC_SAI2_TXC__GPIO4_IO25        0x154
844 +            MX8MP_IOMUXC_SD2_DATA1__GPIO2_IO16        0x140
845 +            MX8MP_IOMUXC_SD1_CMD__GPIO2_IO01        0x154
846 +        >;
847 +    };
848 +
849 +    pinctrl_wwan_reg: wwanprowergrp {
850 +        fsl,pins = <
851 +            MX8MP_IOMUXC_ECSPI2_SCLK__GPIO5_IO10    0x140
852 +        >;
853 +    };
854 +
855 +    pinctrl_usb_host_reg: usbvbusgrp {
856 +        fsl,pins = <
857 +            MX8MP_IOMUXC_ECSPI2_MISO__GPIO5_IO12    0x140
858 +        >;
859 +    };
860 +
861 +    pinctrl_i2c1: i2c1grp {
862 +        fsl,pins = <
863 +            MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL        0x400001c2
864 +            MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA        0x400001c2
865 +        >;
866 +    };
867 +
868 +    pinctrl_i2c2: i2c2grp {
869 +        fsl,pins = <
870 +            MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL        0x400001c2
871 +            MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA        0x400001c2
872 +        >;
873 +    };
874 +
875 +    pinctrl_i2c3: i2c3grp {
876 +        fsl,pins = <
877 +            MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL        0x400001c2
878 +            MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA        0x400001c2
879 +        >;
880 +    };
881 +
882 +    pinctrl_pmic: pmicgrp {
883 +        fsl,pins = <
884 +            MX8MP_IOMUXC_GPIO1_IO03__GPIO1_IO03    0x000001c0
885 +        >;
886 +    };
887 +
888 +    pinctrl_sai3: sai3grp {
889 +        fsl,pins = <
890 +            MX8MP_IOMUXC_SAI3_TXFS__AUDIOMIX_SAI3_TX_SYNC    0xd6
891 +            MX8MP_IOMUXC_SAI3_TXC__AUDIOMIX_SAI3_TX_BCLK    0xd6
892 +            MX8MP_IOMUXC_SAI3_RXD__AUDIOMIX_SAI3_RX_DATA00    0xd6
893 +            MX8MP_IOMUXC_SAI3_TXD__AUDIOMIX_SAI3_TX_DATA00    0xd6
894 +            MX8MP_IOMUXC_SAI3_MCLK__AUDIOMIX_SAI3_MCLK    0xd6
895 +            MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28        0xd6
896 +            MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29        0xd6
897 +        >;
898 +    };
899 +
900 +    pinctrl_uart2: uart2grp {
901 +        fsl,pins = <
902 +            MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX    0x140
903 +            MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX    0x140
904 +        >;
905 +    };
906 +
907 +    pinctrl_uart1: uart1grp {
908 +        fsl,pins = <
909 +            MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX    0x140
910 +            MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX    0x140
911 +        >;
912 +    };
913 +
914 +    pinctrl_usb0_id_grp: usb0grp{
915 +        fsl,pins = <
916 +            MX8MP_IOMUXC_SAI2_TXD0__GPIO4_IO26        0x19
917 +        >;
918 +    };
919 +
920 +    pinctrl_usdhc3: usdhc3grp {
921 +        fsl,pins = <
922 +            MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK    0x190
923 +            MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD    0x1d0
924 +            MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0    0x1d0
925 +            MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1    0x1d0
926 +            MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2    0x1d0
927 +            MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3    0x1d0
928 +            MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4    0x1d0
929 +            MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5    0x1d0
930 +            MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6    0x1d0
931 +            MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7    0x1d0
932 +            MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE    0x190
933 +        >;
934 +    };
935 +
936 +    pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp {
937 +        fsl,pins = <
938 +            MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK    0x194
939 +            MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD    0x1d4
940 +            MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0    0x1d4
941 +            MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1    0x1d4
942 +            MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2    0x1d4
943 +            MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3    0x1d4
944 +            MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4    0x1d4
945 +            MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5    0x1d4
946 +            MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6    0x1d4
947 +            MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7    0x1d4
948 +            MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE    0x194
949 +        >;
950 +    };
951 +
952 +    pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp {
953 +        fsl,pins = <
954 +            MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK    0x196
955 +            MX8MP_IOMUXC_NAND_WP_B__USDHC3_CMD    0x1d6
956 +            MX8MP_IOMUXC_NAND_DATA04__USDHC3_DATA0    0x1d6
957 +            MX8MP_IOMUXC_NAND_DATA05__USDHC3_DATA1    0x1d6
958 +            MX8MP_IOMUXC_NAND_DATA06__USDHC3_DATA2    0x1d6
959 +            MX8MP_IOMUXC_NAND_DATA07__USDHC3_DATA3    0x1d6
960 +            MX8MP_IOMUXC_NAND_RE_B__USDHC3_DATA4    0x1d6
961 +            MX8MP_IOMUXC_NAND_CE2_B__USDHC3_DATA5    0x1d6
962 +            MX8MP_IOMUXC_NAND_CE3_B__USDHC3_DATA6    0x1d6
963 +            MX8MP_IOMUXC_NAND_CLE__USDHC3_DATA7    0x1d6
964 +            MX8MP_IOMUXC_NAND_CE1_B__USDHC3_STROBE    0x196
965 +        >;
966 +    };
967 +
968 +    pinctrl_wdog: wdoggrp {
969 +        fsl,pins = <
970 +            MX8MP_IOMUXC_GPIO1_IO02__WDOG1_WDOG_B    0x166
971 +        >;
972 +    };
973 +};
974 +
975 +/*+---------------+
976 +  | Other Modules |
977 +  +---------------+*/
978 +&vpu_g1 {
979 +    status = "okay";
980 +};
981 +
982 +&vpu_g2 {
983 +    status = "okay";
984 +};
985 +
986 +&vpu_vc8000e {
987 +    status = "okay";
988 +};
989 +
990 +&vpu_v4l2 {
991 +    status = "okay";
992 +};
993 +
994 +&gpu_3d {
995 +    status = "okay";
996 +};
997 +
998 +&gpu_2d {
999 +    status = "okay";
1000 +};
1001 +
1002 +&ml_vipsi {
1003 +    status = "okay";
1004 +};
1005 +
1006 +&mix_gpu_ml {
1007 +    status = "okay";
1008 +};
1009 +
1010 +&cameradev {
1011 +    status = "okay";
1012 +};
1013 +
1014 +&isi_0 {
1015 +    status = "okay";
1016 +
1017 +    cap_device {
1018 +        status = "okay";
1019 +    };
1020 +
1021 +    m2m_device {
1022 +        status = "okay";
1023 +    };
1024 +};
1025 +
1026 +&isi_1 {
1027 +    status = "disabled";
1028 +
1029 +    cap_device {
1030 +        status = "okay";
1031 +    };
1032 +};
1033 diff --git a/arch/arm64/configs/gauguin-imx8mp_defconfig b/arch/arm64/configs/gauguin-imx8mp_defconfig
1034 new file mode 100644
1035 index 000000000..d5f67800e
1036 --- /dev/null
1037 +++ b/arch/arm64/configs/gauguin-imx8mp_defconfig
1038 @@ -0,0 +1,1034 @@
1039 +CONFIG_SYSVIPC=y
1040 +CONFIG_POSIX_MQUEUE=y
1041 +CONFIG_AUDIT=y
1042 +CONFIG_NO_HZ_IDLE=y
1043 +CONFIG_HIGH_RES_TIMERS=y
1044 +CONFIG_BPF_JIT=y
1045 +CONFIG_PREEMPT=y
1046 +CONFIG_IRQ_TIME_ACCOUNTING=y
1047 +CONFIG_BSD_PROCESS_ACCT=y
1048 +CONFIG_BSD_PROCESS_ACCT_V3=y
1049 +CONFIG_IKCONFIG=y
1050 +CONFIG_IKCONFIG_PROC=y
1051 +CONFIG_NUMA_BALANCING=y
1052 +CONFIG_MEMCG=y
1053 +CONFIG_BLK_CGROUP=y
1054 +CONFIG_CGROUP_PIDS=y
1055 +CONFIG_CGROUP_FREEZER=y
1056 +CONFIG_CGROUP_HUGETLB=y
1057 +CONFIG_CPUSETS=y
1058 +CONFIG_CGROUP_DEVICE=y
1059 +CONFIG_CGROUP_CPUACCT=y
1060 +CONFIG_CGROUP_PERF=y
1061 +CONFIG_NAMESPACES=y
1062 +CONFIG_USER_NS=y
1063 +CONFIG_SCHED_AUTOGROUP=y
1064 +CONFIG_SYSFS_DEPRECATED=y
1065 +CONFIG_SYSFS_DEPRECATED_V2=y
1066 +CONFIG_RELAY=y
1067 +CONFIG_BLK_DEV_INITRD=y
1068 +CONFIG_KALLSYMS_ALL=y
1069 +CONFIG_EMBEDDED=y
1070 +# CONFIG_COMPAT_BRK is not set
1071 +CONFIG_PROFILING=y
1072 +CONFIG_ARCH_LAYERSCAPE=y
1073 +CONFIG_ARCH_KEEMBAY=y
1074 +CONFIG_ARCH_MXC=y
1075 +CONFIG_ARCH_S32=y
1076 +CONFIG_SOC_S32V234=y
1077 +CONFIG_ARM64_VA_BITS_48=y
1078 +CONFIG_SCHED_MC=y
1079 +CONFIG_SCHED_SMT=y
1080 +CONFIG_NUMA=y
1081 +CONFIG_KEXEC=y
1082 +CONFIG_KEXEC_FILE=y
1083 +CONFIG_CRASH_DUMP=y
1084 +CONFIG_XEN=y
1085 +CONFIG_FORCE_MAX_ZONEORDER=14
1086 +CONFIG_COMPAT=y
1087 +CONFIG_RANDOMIZE_BASE=y
1088 +CONFIG_PM_DEBUG=y
1089 +CONFIG_PM_TEST_SUSPEND=y
1090 +CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
1091 +CONFIG_ENERGY_MODEL=y
1092 +CONFIG_ARM_CPUIDLE=y
1093 +CONFIG_ARM_PSCI_CPUIDLE=y
1094 +CONFIG_CPU_FREQ=y
1095 +CONFIG_CPU_FREQ_STAT=y
1096 +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
1097 +CONFIG_CPU_FREQ_GOV_POWERSAVE=y
1098 +CONFIG_CPU_FREQ_GOV_USERSPACE=y
1099 +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
1100 +CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
1101 +CONFIG_CPUFREQ_DT=y
1102 +CONFIG_ACPI_CPPC_CPUFREQ=m
1103 +CONFIG_ARM_SCPI_CPUFREQ=y
1104 +CONFIG_ARM_IMX_CPUFREQ_DT=y
1105 +CONFIG_ARM_SCMI_CPUFREQ=y
1106 +CONFIG_QORIQ_CPUFREQ=y
1107 +CONFIG_ACPI=y
1108 +CONFIG_ACPI_APEI=y
1109 +CONFIG_ACPI_APEI_GHES=y
1110 +CONFIG_ACPI_APEI_MEMORY_FAILURE=y
1111 +CONFIG_ACPI_APEI_EINJ=y
1112 +CONFIG_VIRTUALIZATION=y
1113 +CONFIG_KVM=y
1114 +CONFIG_ARM64_CRYPTO=y
1115 +CONFIG_CRYPTO_SHA1_ARM64_CE=y
1116 +CONFIG_CRYPTO_SHA2_ARM64_CE=y
1117 +CONFIG_CRYPTO_SHA512_ARM64_CE=m
1118 +CONFIG_CRYPTO_SHA3_ARM64=m
1119 +CONFIG_CRYPTO_SM3_ARM64_CE=m
1120 +CONFIG_CRYPTO_GHASH_ARM64_CE=y
1121 +CONFIG_CRYPTO_CRCT10DIF_ARM64_CE=m
1122 +CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
1123 +CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
1124 +CONFIG_CRYPTO_CHACHA20_NEON=m
1125 +CONFIG_CRYPTO_AES_ARM64_BS=m
1126 +CONFIG_JUMP_LABEL=y
1127 +CONFIG_MODULES=y
1128 +CONFIG_MODULE_UNLOAD=y
1129 +CONFIG_MODVERSIONS=y
1130 +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
1131 +CONFIG_KSM=y
1132 +CONFIG_MEMORY_FAILURE=y
1133 +CONFIG_TRANSPARENT_HUGEPAGE=y
1134 +CONFIG_NET=y
1135 +CONFIG_PACKET=y
1136 +CONFIG_UNIX=y
1137 +CONFIG_TLS=y
1138 +CONFIG_TLS_DEVICE=y
1139 +CONFIG_INET=y
1140 +CONFIG_IP_MULTICAST=y
1141 +CONFIG_IP_PNP=y
1142 +CONFIG_IP_PNP_DHCP=y
1143 +CONFIG_IP_PNP_BOOTP=y
1144 +CONFIG_IPV6_SIT=m
1145 +CONFIG_NETFILTER=y
1146 +CONFIG_NF_CONNTRACK=m
1147 +CONFIG_NF_CONNTRACK_EVENTS=y
1148 +CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
1149 +CONFIG_NETFILTER_XT_TARGET_LOG=m
1150 +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
1151 +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
1152 +CONFIG_IP_NF_IPTABLES=m
1153 +CONFIG_IP_NF_FILTER=m
1154 +CONFIG_IP_NF_TARGET_REJECT=m
1155 +CONFIG_IP_NF_NAT=m
1156 +CONFIG_IP_NF_TARGET_MASQUERADE=m
1157 +CONFIG_IP_NF_MANGLE=m
1158 +CONFIG_IP6_NF_IPTABLES=m
1159 +CONFIG_IP6_NF_FILTER=m
1160 +CONFIG_IP6_NF_TARGET_REJECT=m
1161 +CONFIG_IP6_NF_MANGLE=m
1162 +CONFIG_IP6_NF_NAT=m
1163 +CONFIG_IP6_NF_TARGET_MASQUERADE=m
1164 +CONFIG_BRIDGE=y
1165 +CONFIG_BRIDGE_VLAN_FILTERING=y
1166 +CONFIG_NET_DSA=m
1167 +CONFIG_NET_DSA_TAG_OCELOT=m
1168 +CONFIG_NET_DSA_TAG_OCELOT_8021Q=m
1169 +CONFIG_VLAN_8021Q_GVRP=y
1170 +CONFIG_VLAN_8021Q_MVRP=y
1171 +CONFIG_LLC2=y
1172 +CONFIG_NET_SCHED=y
1173 +CONFIG_NET_SCH_MULTIQ=m
1174 +CONFIG_NET_SCH_CBS=m
1175 +CONFIG_NET_SCH_ETF=m
1176 +CONFIG_NET_SCH_TAPRIO=m
1177 +CONFIG_NET_SCH_MQPRIO=m
1178 +CONFIG_NET_SCH_INGRESS=m
1179 +CONFIG_NET_CLS_BASIC=m
1180 +CONFIG_NET_CLS_TCINDEX=m
1181 +CONFIG_NET_CLS_FLOWER=m
1182 +CONFIG_NET_CLS_ACT=y
1183 +CONFIG_NET_ACT_GACT=m
1184 +CONFIG_NET_ACT_MIRRED=m
1185 +CONFIG_NET_ACT_GATE=m
1186 +CONFIG_TSN=y
1187 +CONFIG_QRTR=m
1188 +CONFIG_QRTR_SMD=m
1189 +CONFIG_QRTR_TUN=m
1190 +CONFIG_NET_PKTGEN=m
1191 +CONFIG_CAN=m
1192 +CONFIG_CAN_FLEXCAN=m
1193 +CONFIG_BT=y
1194 +CONFIG_BT_RFCOMM=y
1195 +CONFIG_BT_RFCOMM_TTY=y
1196 +CONFIG_BT_BNEP=y
1197 +CONFIG_BT_BNEP_MC_FILTER=y
1198 +CONFIG_BT_BNEP_PROTO_FILTER=y
1199 +CONFIG_BT_HIDP=y
1200 +CONFIG_BT_LEDS=y
1201 +# CONFIG_BT_DEBUGFS is not set
1202 +CONFIG_BT_HCIBTUSB=m
1203 +CONFIG_BT_HCIUART=y
1204 +CONFIG_BT_HCIUART_BCSP=y
1205 +CONFIG_BT_HCIUART_ATH3K=y
1206 +CONFIG_BT_HCIUART_LL=y
1207 +CONFIG_BT_HCIUART_3WIRE=y
1208 +CONFIG_BT_HCIUART_BCM=y
1209 +CONFIG_BT_HCIUART_QCA=y
1210 +CONFIG_BT_HCIVHCI=y
1211 +CONFIG_CFG80211=y
1212 +CONFIG_NL80211_TESTMODE=y
1213 +CONFIG_CFG80211_WEXT=y
1214 +CONFIG_MAC80211=y
1215 +CONFIG_MAC80211_LEDS=y
1216 +CONFIG_NET_9P=y
1217 +CONFIG_NET_9P_VIRTIO=y
1218 +CONFIG_NFC=m
1219 +CONFIG_NFC_NCI=m
1220 +CONFIG_NFC_S3FWRN5_I2C=m
1221 +CONFIG_DEVTMPFS=y
1222 +CONFIG_DEVTMPFS_MOUNT=y
1223 +CONFIG_FW_LOADER_USER_HELPER=y
1224 +CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
1225 +CONFIG_BRCMSTB_GISB_ARB=y
1226 +CONFIG_VEXPRESS_CONFIG=y
1227 +CONFIG_FSL_MC_UAPI_SUPPORT=y
1228 +CONFIG_ARM_SCMI_PROTOCOL=y
1229 +CONFIG_ARM_SCPI_PROTOCOL=y
1230 +CONFIG_EFI_CAPSULE_LOADER=y
1231 +CONFIG_IMX_DSP=y
1232 +CONFIG_IMX_SCU=y
1233 +CONFIG_IMX_SCU_PD=y
1234 +CONFIG_GNSS=m
1235 +CONFIG_GNSS_MTK_SERIAL=m
1236 +CONFIG_MTD=y
1237 +CONFIG_MTD_CMDLINE_PARTS=y
1238 +CONFIG_MTD_BLOCK=y
1239 +CONFIG_MTD_CFI=y
1240 +CONFIG_MTD_CFI_ADV_OPTIONS=y
1241 +CONFIG_MTD_CFI_INTELEXT=y
1242 +CONFIG_MTD_CFI_AMDSTD=y
1243 +CONFIG_MTD_CFI_STAA=y
1244 +CONFIG_MTD_PHYSMAP=y
1245 +CONFIG_MTD_PHYSMAP_OF=y
1246 +CONFIG_MTD_DATAFLASH=y
1247 +CONFIG_MTD_SST25L=y
1248 +CONFIG_MTD_RAW_NAND=y
1249 +CONFIG_MTD_NAND_DENALI_DT=y
1250 +CONFIG_MTD_NAND_GPMI_NAND=y
1251 +CONFIG_MTD_NAND_FSL_IFC=y
1252 +CONFIG_MTD_SPI_NOR=y
1253 +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
1254 +CONFIG_MTD_UBI=y
1255 +CONFIG_BLK_DEV_LOOP=y
1256 +CONFIG_BLK_DEV_NBD=m
1257 +CONFIG_XEN_BLKDEV_BACKEND=m
1258 +CONFIG_VIRTIO_BLK=y
1259 +CONFIG_SRAM=y
1260 +CONFIG_EEPROM_AT24=m
1261 +CONFIG_EEPROM_AT25=m
1262 +CONFIG_UACCE=m
1263 +CONFIG_RAID_ATTRS=m
1264 +# CONFIG_SCSI_PROC_FS is not set
1265 +CONFIG_BLK_DEV_SD=y
1266 +CONFIG_SCSI_SAS_ATA=y
1267 +CONFIG_SCSI_HISI_SAS=y
1268 +CONFIG_SCSI_UFSHCD=y
1269 +CONFIG_SCSI_UFSHCD_PLATFORM=y
1270 +CONFIG_ATA=y
1271 +CONFIG_SATA_AHCI_PLATFORM=y
1272 +CONFIG_AHCI_IMX=y
1273 +CONFIG_AHCI_CEVA=y
1274 +CONFIG_AHCI_XGENE=y
1275 +CONFIG_AHCI_QORIQ=y
1276 +CONFIG_PATA_PLATFORM=y
1277 +CONFIG_PATA_OF_PLATFORM=y
1278 +CONFIG_MD=y
1279 +CONFIG_BLK_DEV_MD=m
1280 +CONFIG_BLK_DEV_DM=m
1281 +CONFIG_DM_CRYPT=m
1282 +CONFIG_DM_MIRROR=m
1283 +CONFIG_DM_ZERO=m
1284 +CONFIG_NETDEVICES=y
1285 +CONFIG_MACVLAN=m
1286 +CONFIG_MACVTAP=m
1287 +CONFIG_TUN=y
1288 +CONFIG_VETH=m
1289 +CONFIG_VIRTIO_NET=y
1290 +CONFIG_AMD_XGBE=y
1291 +CONFIG_BCMGENET=m
1292 +CONFIG_MACB=y
1293 +CONFIG_FEC=y
1294 +CONFIG_FEC_UIO=y
1295 +CONFIG_FSL_FMAN=y
1296 +CONFIG_FSL_DPAA_ETH=y
1297 +CONFIG_FSL_DPAA2_ETH=y
1298 +CONFIG_FSL_DPAA2_MAC=y
1299 +CONFIG_FSL_DPAA2_SWITCH=y
1300 +CONFIG_FSL_ENETC_IERB=y
1301 +CONFIG_HIX5HD2_GMAC=y
1302 +CONFIG_HNS_DSAF=y
1303 +CONFIG_HNS_ENET=y
1304 +CONFIG_MVMDIO=y
1305 +CONFIG_MSCC_OCELOT_SWITCH=y
1306 +CONFIG_QCOM_EMAC=m
1307 +CONFIG_RMNET=m
1308 +CONFIG_SMC91X=y
1309 +CONFIG_SMSC911X=y
1310 +CONFIG_STMMAC_ETH=y
1311 +CONFIG_DWMAC_GENERIC=m
1312 +CONFIG_AQUANTIA_PHY=y
1313 +CONFIG_BROADCOM_PHY=m
1314 +CONFIG_BCM54140_PHY=m
1315 +CONFIG_INPHI_PHY=y
1316 +CONFIG_MARVELL_PHY=m
1317 +CONFIG_MARVELL_10G_PHY=m
1318 +CONFIG_MICREL_PHY=y
1319 +CONFIG_MICROSEMI_PHY=y
1320 +CONFIG_NXP_TJA11XX_PHY=y
1321 +CONFIG_AT803X_PHY=y
1322 +CONFIG_REALTEK_PHY=y
1323 +CONFIG_ROCKCHIP_PHY=y
1324 +CONFIG_VITESSE_PHY=y
1325 +CONFIG_MDIO_BITBANG=y
1326 +CONFIG_MDIO_BUS_MUX_MULTIPLEXER=y
1327 +CONFIG_MDIO_BUS_MUX_MMIOREG=y
1328 +CONFIG_PPP=y
1329 +CONFIG_PPP_BSDCOMP=y
1330 +CONFIG_PPP_DEFLATE=y
1331 +CONFIG_PPP_FILTER=y
1332 +CONFIG_PPP_MPPE=y
1333 +CONFIG_PPP_MULTILINK=y
1334 +CONFIG_PPPOE=y
1335 +CONFIG_PPP_ASYNC=y
1336 +CONFIG_PPP_SYNC_TTY=y
1337 +CONFIG_SLIP=y
1338 +CONFIG_USB_PEGASUS=m
1339 +CONFIG_USB_RTL8150=m
1340 +CONFIG_USB_RTL8152=y
1341 +CONFIG_USB_LAN78XX=m
1342 +CONFIG_USB_USBNET=y
1343 +CONFIG_USB_NET_AX8817X=m
1344 +CONFIG_USB_NET_AX88179_178A=m
1345 +CONFIG_USB_NET_CDCETHER=m
1346 +CONFIG_USB_NET_CDC_NCM=m
1347 +CONFIG_USB_NET_DM9601=m
1348 +CONFIG_USB_NET_SR9800=m
1349 +CONFIG_USB_NET_SMSC75XX=m
1350 +CONFIG_USB_NET_SMSC95XX=m
1351 +CONFIG_USB_NET_NET1080=m
1352 +CONFIG_USB_NET_PLUSB=m
1353 +CONFIG_USB_NET_MCS7830=m
1354 +CONFIG_USB_NET_CDC_SUBSET=m
1355 +CONFIG_USB_NET_ZAURUS=m
1356 +CONFIG_USB_NET_QMI_WWAN=y
1357 +CONFIG_HOSTAP=y
1358 +CONFIG_WL18XX=m
1359 +CONFIG_WLCORE_SDIO=m
1360 +CONFIG_XEN_NETDEV_BACKEND=m
1361 +CONFIG_INPUT_EVDEV=y
1362 +CONFIG_KEYBOARD_ADC=m
1363 +CONFIG_KEYBOARD_GPIO=y
1364 +CONFIG_KEYBOARD_RPMSG=y
1365 +CONFIG_KEYBOARD_SNVS_PWRKEY=y
1366 +CONFIG_KEYBOARD_BBNSM_PWRKEY=y
1367 +CONFIG_KEYBOARD_IMX_SC_PWRKEY=y
1368 +CONFIG_KEYBOARD_CROS_EC=y
1369 +CONFIG_INPUT_TOUCHSCREEN=y
1370 +CONFIG_TOUCHSCREEN_ATMEL_MXT=m
1371 +CONFIG_TOUCHSCREEN_EXC3000=m
1372 +CONFIG_TOUCHSCREEN_GOODIX=m
1373 +CONFIG_TOUCHSCREEN_EDT_FT5X06=m
1374 +CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_I2C=m
1375 +CONFIG_INPUT_MISC=y
1376 +CONFIG_INPUT_PWM_VIBRA=m
1377 +# CONFIG_SERIO_SERPORT is not set
1378 +CONFIG_SERIO_AMBAKMI=y
1379 +CONFIG_LEGACY_PTY_COUNT=16
1380 +CONFIG_SERIAL_8250=y
1381 +CONFIG_SERIAL_8250_CONSOLE=y
1382 +CONFIG_SERIAL_8250_EXTENDED=y
1383 +CONFIG_SERIAL_8250_SHARE_IRQ=y
1384 +CONFIG_SERIAL_8250_DW=y
1385 +CONFIG_SERIAL_OF_PLATFORM=y
1386 +CONFIG_SERIAL_AMBA_PL011=y
1387 +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
1388 +CONFIG_SERIAL_IMX=y
1389 +CONFIG_SERIAL_IMX_CONSOLE=y
1390 +CONFIG_SERIAL_XILINX_PS_UART=y
1391 +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y
1392 +CONFIG_SERIAL_FSL_LPUART=y
1393 +CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
1394 +CONFIG_SERIAL_FSL_LINFLEXUART=y
1395 +CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
1396 +CONFIG_SERIAL_DEV_BUS=y
1397 +CONFIG_VIRTIO_CONSOLE=y
1398 +CONFIG_IPMI_HANDLER=m
1399 +CONFIG_IPMI_DEVICE_INTERFACE=m
1400 +CONFIG_IPMI_SI=m
1401 +CONFIG_TCG_TPM=y
1402 +CONFIG_TCG_TIS_I2C_INFINEON=y
1403 +CONFIG_I2C_CHARDEV=y
1404 +CONFIG_I2C_MUX=y
1405 +CONFIG_I2C_MUX_PCA954x=y
1406 +CONFIG_I2C_DESIGNWARE_PLATFORM=y
1407 +CONFIG_I2C_GPIO=m
1408 +CONFIG_I2C_IMX=y
1409 +CONFIG_I2C_IMX_LPI2C=y
1410 +CONFIG_I2C_RK3X=y
1411 +CONFIG_I2C_RPBUS=y
1412 +CONFIG_I2C_CROS_EC_TUNNEL=y
1413 +CONFIG_XEN_I2C_BACKEND=y
1414 +CONFIG_I3C=y
1415 +CONFIG_SVC_I3C_MASTER=y
1416 +CONFIG_SPI=y
1417 +CONFIG_SPI_CADENCE_QUADSPI=y
1418 +CONFIG_SPI_DESIGNWARE=m
1419 +CONFIG_SPI_DW_DMA=y
1420 +CONFIG_SPI_DW_MMIO=m
1421 +CONFIG_SPI_FSL_LPSPI=y
1422 +CONFIG_SPI_FSL_QUADSPI=y
1423 +CONFIG_SPI_NXP_FLEXSPI=y
1424 +CONFIG_SPI_IMX=y
1425 +CONFIG_SPI_FSL_DSPI=y
1426 +CONFIG_SPI_PL022=y
1427 +CONFIG_SPI_ROCKCHIP=y
1428 +CONFIG_SPI_SPIDEV=y
1429 +CONFIG_SPI_SLAVE=y
1430 +CONFIG_SPI_SLAVE_TIME=y
1431 +CONFIG_SPI_SLAVE_SYSTEM_CONTROL=y
1432 +CONFIG_SPMI=y
1433 +CONFIG_PINCTRL_SINGLE=y
1434 +CONFIG_PINCTRL_MAX77620=y
1435 +CONFIG_PINCTRL_IMX8MM=y
1436 +CONFIG_PINCTRL_IMX8MN=y
1437 +CONFIG_PINCTRL_IMX8MP=y
1438 +CONFIG_PINCTRL_IMX8MQ=y
1439 +CONFIG_PINCTRL_IMX8QM=y
1440 +CONFIG_PINCTRL_IMX8QXP=y
1441 +CONFIG_PINCTRL_IMX8DXL=y
1442 +CONFIG_PINCTRL_IMX8ULP=y
1443 +CONFIG_PINCTRL_IMX93=y
1444 +CONFIG_PINCTRL_S32V234=y
1445 +CONFIG_GPIO_SYSFS=y
1446 +CONFIG_GPIO_ALTERA=m
1447 +CONFIG_GPIO_DWAPB=y
1448 +CONFIG_GPIO_MB86S7X=y
1449 +CONFIG_GPIO_MPC8XXX=y
1450 +CONFIG_GPIO_PL061=y
1451 +CONFIG_GPIO_IMX_RPMSG=y
1452 +CONFIG_GPIO_WCD934X=m
1453 +CONFIG_GPIO_XGENE=y
1454 +CONFIG_GPIO_MAX732X=y
1455 +CONFIG_GPIO_PCA953X=y
1456 +CONFIG_GPIO_PCA953X_IRQ=y
1457 +CONFIG_GPIO_ADP5585=y
1458 +CONFIG_GPIO_BD9571MWV=m
1459 +CONFIG_GPIO_MAX77620=y
1460 +CONFIG_GPIO_SL28CPLD=m
1461 +CONFIG_POWER_RESET_BRCMSTB=y
1462 +CONFIG_POWER_RESET_XGENE=y
1463 +CONFIG_POWER_RESET_SYSCON=y
1464 +CONFIG_SYSCON_REBOOT_MODE=y
1465 +CONFIG_BATTERY_SBS=m
1466 +CONFIG_BATTERY_BQ27XXX=y
1467 +CONFIG_BATTERY_MAX17042=m
1468 +CONFIG_CHARGER_BQ25890=m
1469 +CONFIG_CHARGER_BQ25980=m
1470 +CONFIG_SENSORS_ARM_SCMI=y
1471 +CONFIG_SENSORS_ARM_SCPI=y
1472 +CONFIG_SENSORS_FP9931=y
1473 +CONFIG_SENSORS_LM90=m
1474 +CONFIG_SENSORS_PWM_FAN=m
1475 +CONFIG_SENSORS_SL28CPLD=m
1476 +CONFIG_SENSORS_INA2XX=m
1477 +CONFIG_SENSORS_INA3221=m
1478 +CONFIG_THERMAL_WRITABLE_TRIPS=y
1479 +CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
1480 +CONFIG_CPU_THERMAL=y
1481 +CONFIG_THERMAL_EMULATION=y
1482 +CONFIG_IMX_SC_THERMAL=y
1483 +CONFIG_IMX8MM_THERMAL=y
1484 +CONFIG_DEVICE_THERMAL=y
1485 +CONFIG_QORIQ_THERMAL=y
1486 +CONFIG_WATCHDOG=y
1487 +CONFIG_SL28CPLD_WATCHDOG=m
1488 +CONFIG_ARM_SP805_WATCHDOG=y
1489 +CONFIG_ARM_SBSA_WATCHDOG=y
1490 +CONFIG_DW_WATCHDOG=y
1491 +CONFIG_IMX2_WDT=y
1492 +CONFIG_IMX_SC_WDT=y
1493 +CONFIG_IMX7ULP_WDT=y
1494 +CONFIG_ARM_SMC_WATCHDOG=y
1495 +CONFIG_XEN_WDT=y
1496 +CONFIG_MFD_ADP5585=y
1497 +CONFIG_MFD_BD9571MWV=y
1498 +CONFIG_MFD_AXP20X_I2C=y
1499 +CONFIG_MFD_IMX_MIX=y
1500 +CONFIG_MFD_HI6421_PMIC=y
1501 +CONFIG_MFD_FP9931=y
1502 +CONFIG_MFD_MAX77620=y
1503 +CONFIG_MFD_MT6397=y
1504 +CONFIG_MFD_RK808=y
1505 +CONFIG_MFD_SEC_CORE=y
1506 +CONFIG_MFD_SL28CPLD=y
1507 +CONFIG_MFD_ROHM_BD718XX=y
1508 +CONFIG_MFD_WCD934X=m
1509 +CONFIG_REGULATOR_FIXED_VOLTAGE=y
1510 +CONFIG_REGULATOR_AXP20X=y
1511 +CONFIG_REGULATOR_BD718XX=y
1512 +CONFIG_REGULATOR_BD9571MWV=y
1513 +CONFIG_REGULATOR_FAN53555=y
1514 +CONFIG_REGULATOR_GPIO=y
1515 +CONFIG_REGULATOR_HI6421V530=y
1516 +CONFIG_REGULATOR_MAX77620=y
1517 +CONFIG_REGULATOR_MAX8973=y
1518 +CONFIG_REGULATOR_FP9931=y
1519 +CONFIG_REGULATOR_MP8859=y
1520 +CONFIG_REGULATOR_MT6358=y
1521 +CONFIG_REGULATOR_MT6397=y
1522 +CONFIG_REGULATOR_PCA9450=y
1523 +CONFIG_REGULATOR_PF8X00=y
1524 +CONFIG_REGULATOR_PFUZE100=y
1525 +CONFIG_REGULATOR_PWM=y
1526 +CONFIG_REGULATOR_QCOM_SPMI=y
1527 +CONFIG_REGULATOR_RK808=y
1528 +CONFIG_REGULATOR_S2MPS11=y
1529 +CONFIG_REGULATOR_TPS65132=m
1530 +CONFIG_REGULATOR_VCTRL=m
1531 +CONFIG_RC_CORE=m
1532 +CONFIG_RC_DECODERS=y
1533 +CONFIG_IR_NEC_DECODER=m
1534 +CONFIG_IR_RC5_DECODER=m
1535 +CONFIG_IR_RC6_DECODER=m
1536 +CONFIG_IR_JVC_DECODER=m
1537 +CONFIG_IR_SONY_DECODER=m
1538 +CONFIG_IR_SANYO_DECODER=m
1539 +CONFIG_IR_SHARP_DECODER=m
1540 +CONFIG_IR_MCE_KBD_DECODER=m
1541 +CONFIG_IR_XMP_DECODER=m
1542 +CONFIG_IR_IMON_DECODER=m
1543 +CONFIG_IR_RCMM_DECODER=m
1544 +CONFIG_RC_DEVICES=y
1545 +CONFIG_IR_GPIO_CIR=m
1546 +CONFIG_MEDIA_SUPPORT=y
1547 +CONFIG_MEDIA_SUPPORT_FILTER=y
1548 +CONFIG_MEDIA_CAMERA_SUPPORT=y
1549 +CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
1550 +CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
1551 +CONFIG_MEDIA_SDR_SUPPORT=y
1552 +CONFIG_MEDIA_PLATFORM_SUPPORT=y
1553 +# CONFIG_DVB_NET is not set
1554 +CONFIG_MEDIA_USB_SUPPORT=y
1555 +CONFIG_USB_VIDEO_CLASS=m
1556 +CONFIG_V4L_PLATFORM_DRIVERS=y
1557 +CONFIG_VIDEO_IMX8_JPEG=m
1558 +CONFIG_VIDEO_AMPHION_VPU=y
1559 +CONFIG_VIDEO_MXC_CAPTURE=y
1560 +CONFIG_VIDEO_MX8_CAPTURE=y
1561 +CONFIG_VIDEO_MXC_CSI_CAMERA=y
1562 +CONFIG_MXC_MIPI_CSI=y
1563 +CONFIG_MXC_CAMERA_OV5640_MIPI_V2=y
1564 +CONFIG_V4L_MEM2MEM_DRIVERS=y
1565 +CONFIG_SDR_PLATFORM_DRIVERS=y
1566 +CONFIG_VIDEO_IMX219=m
1567 +CONFIG_VIDEO_OV5640=y
1568 +CONFIG_VIDEO_OV5645=m
1569 +CONFIG_VIDEO_MT9M114=y
1570 +CONFIG_VIDEO_AP1302=y
1571 +CONFIG_IMX_DPU_CORE=y
1572 +CONFIG_IMX_LCDIF_CORE=y
1573 +CONFIG_IMX_LCDIFV3_CORE=y
1574 +CONFIG_DRM=y
1575 +CONFIG_DRM_I2C_CH7006=m
1576 +CONFIG_DRM_I2C_SIL164=m
1577 +CONFIG_DRM_I2C_NXP_TDA998X=m
1578 +CONFIG_DRM_MALI_DISPLAY=m
1579 +CONFIG_DRM_RCAR_DW_HDMI=m
1580 +CONFIG_DRM_RCAR_LVDS=m
1581 +CONFIG_DRM_PANEL_BOE_TV101WUM_NL6=m
1582 +CONFIG_DRM_PANEL_LVDS=m
1583 +CONFIG_DRM_PANEL_SIMPLE=y
1584 +CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m
1585 +CONFIG_DRM_PANEL_ONTAT_KD50G21_40NT_A1=y
1586 +CONFIG_DRM_PANEL_RAYDIUM_RM67191=y
1587 +CONFIG_DRM_PANEL_RAYDIUM_RM68200=y
1588 +CONFIG_DRM_PANEL_ROCKTECK_HIMAX8394F=y
1589 +CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
1590 +CONFIG_DRM_PANEL_SITRONIX_ST7703=m
1591 +CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA=m
1592 +CONFIG_DRM_PANEL_WKS_101WX001=y
1593 +CONFIG_DRM_DISPLAY_CONNECTOR=m
1594 +CONFIG_DRM_LONTIUM_LT8912B=m
1595 +CONFIG_DRM_LONTIUM_LT9611=m
1596 +CONFIG_DRM_LONTIUM_LT9611UXC=m
1597 +CONFIG_DRM_FSL_IMX_LVDS_BRIDGE=y
1598 +CONFIG_DRM_NWL_MIPI_DSI=y
1599 +CONFIG_DRM_NXP_SEIKO_43WVFIG=y
1600 +CONFIG_DRM_PARADE_PS8640=m
1601 +CONFIG_DRM_SII902X=m
1602 +CONFIG_DRM_SIMPLE_BRIDGE=m
1603 +CONFIG_DRM_THINE_THC63LVD1024=m
1604 +CONFIG_DRM_TI_SN65DSI86=m
1605 +CONFIG_DRM_I2C_ADV7511=y
1606 +CONFIG_DRM_I2C_ADV7511_AUDIO=y
1607 +CONFIG_DRM_CDNS_HDCP=y
1608 +CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
1609 +CONFIG_DRM_DW_HDMI_I2S_AUDIO=m
1610 +CONFIG_DRM_DW_HDMI_GP_AUDIO=y
1611 +CONFIG_DRM_DW_HDMI_CEC=m
1612 +CONFIG_DRM_ITE_IT6263=y
1613 +CONFIG_DRM_ITE_IT6161=y
1614 +CONFIG_DRM_IMX=y
1615 +CONFIG_DRM_IMX_LCDIF_MUX_DISPLAY=y
1616 +CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
1617 +CONFIG_DRM_IMX_TVE=y
1618 +CONFIG_DRM_IMX_LDB=y
1619 +CONFIG_DRM_IMX8QM_LDB=y
1620 +CONFIG_DRM_IMX8QXP_LDB=y
1621 +CONFIG_DRM_IMX8MP_LDB=y
1622 +CONFIG_DRM_IMX93_LDB=y
1623 +CONFIG_DRM_IMX93_PARALLEL_DISPLAY_FORMAT=y
1624 +CONFIG_DRM_IMX_DW_MIPI_DSI=y
1625 +CONFIG_DRM_IMX_HDMI=y
1626 +CONFIG_DRM_IMX_SEC_DSIM=y
1627 +CONFIG_DRM_IMX_DCNANO=y
1628 +CONFIG_DRM_IMX_DCSS=y
1629 +CONFIG_DRM_IMX_CDNS_MHDP=y
1630 +CONFIG_DRM_ETNAVIV=m
1631 +CONFIG_DRM_HISI_KIRIN=m
1632 +CONFIG_DRM_MXSFB=y
1633 +CONFIG_DRM_PL111=m
1634 +CONFIG_DRM_LIMA=m
1635 +CONFIG_DRM_PANFROST=m
1636 +CONFIG_DRM_LEGACY=y
1637 +CONFIG_FB=y
1638 +CONFIG_FB_ARMCLCD=y
1639 +CONFIG_FB_EFI=y
1640 +CONFIG_FB_MXC_EINK_V2_PANEL=y
1641 +CONFIG_BACKLIGHT_PWM=y
1642 +CONFIG_BACKLIGHT_LP855X=m
1643 +CONFIG_FRAMEBUFFER_CONSOLE=y
1644 +CONFIG_LOGO=y
1645 +# CONFIG_LOGO_LINUX_MONO is not set
1646 +# CONFIG_LOGO_LINUX_VGA16 is not set
1647 +CONFIG_SOUND=y
1648 +CONFIG_SND=y
1649 +CONFIG_SND_ALOOP=m
1650 +CONFIG_SND_USB_AUDIO=m
1651 +CONFIG_SND_SOC=y
1652 +CONFIG_SND_SOC_FSL_ASRC=m
1653 +CONFIG_SND_SOC_FSL_MQS=m
1654 +CONFIG_SND_SOC_FSL_MICFIL=m
1655 +CONFIG_SND_SOC_FSL_EASRC=m
1656 +CONFIG_SND_SOC_FSL_XCVR=m
1657 +CONFIG_SND_SOC_FSL_ESAI_CLIENT=y
1658 +CONFIG_SND_SOC_FSL_RPMSG=m
1659 +CONFIG_SND_IMX_SOC=m
1660 +CONFIG_SND_SOC_IMX_SGTL5000=m
1661 +CONFIG_SND_SOC_IMX_SPDIF=m
1662 +CONFIG_SND_SOC_FSL_ASOC_CARD=m
1663 +CONFIG_SND_SOC_IMX_AUDMIX=m
1664 +CONFIG_SND_SOC_IMX_HDMI=m
1665 +CONFIG_SND_SOC_IMX_CARD=m
1666 +CONFIG_SND_SOC_IMX_PDM_MIC=m
1667 +CONFIG_SND_SOC_IMX_PCM512X=m
1668 +CONFIG_SND_SOC_SOF_TOPLEVEL=y
1669 +CONFIG_SND_SOC_SOF_OF=m
1670 +CONFIG_SND_SOC_SOF_IMX_TOPLEVEL=y
1671 +CONFIG_SND_SOC_SOF_IMX8=m
1672 +CONFIG_SND_SOC_SOF_IMX8M=m
1673 +CONFIG_SND_SOC_SOF_IMX8ULP=m
1674 +CONFIG_SND_SOC_AK4613=m
1675 +CONFIG_SND_SOC_BT_SCO=y
1676 +CONFIG_SND_SOC_CROS_EC_CODEC=m
1677 +CONFIG_SND_SOC_CS42XX8_I2C=y
1678 +CONFIG_SND_SOC_DMIC=m
1679 +CONFIG_SND_SOC_ES7134=m
1680 +CONFIG_SND_SOC_ES7241=m
1681 +CONFIG_SND_SOC_GTM601=m
1682 +CONFIG_SND_SOC_MAX98357A=m
1683 +CONFIG_SND_SOC_MAX98927=m
1684 +CONFIG_SND_SOC_MSM8916_WCD_ANALOG=m
1685 +CONFIG_SND_SOC_MSM8916_WCD_DIGITAL=m
1686 +CONFIG_SND_SOC_PCM3168A_I2C=m
1687 +CONFIG_SND_SOC_RT5659=m
1688 +CONFIG_SND_SOC_SIMPLE_AMPLIFIER=m
1689 +CONFIG_SND_SOC_SIMPLE_MUX=m
1690 +CONFIG_SND_SOC_SPDIF=m
1691 +CONFIG_SND_SOC_TAS571X=m
1692 +CONFIG_SND_SOC_WCD934X=m
1693 +CONFIG_SND_SOC_WM8524=y
1694 +CONFIG_SND_SOC_WM8904=m
1695 +CONFIG_SND_SOC_WM8960=m
1696 +CONFIG_SND_SOC_WM8962=m
1697 +CONFIG_SND_SOC_WSA881X=m
1698 +CONFIG_SND_SOC_RPMSG_WM8960=m
1699 +CONFIG_SND_SOC_RPMSG_AK4497=m
1700 +CONFIG_SND_SOC_NAU8810=m
1701 +CONFIG_SND_SOC_NAU8822=m
1702 +CONFIG_SND_SOC_LPASS_WSA_MACRO=m
1703 +CONFIG_SND_SOC_LPASS_VA_MACRO=m
1704 +CONFIG_SND_SIMPLE_CARD=y
1705 +CONFIG_SND_AUDIO_GRAPH_CARD=y
1706 +CONFIG_HID_A4TECH=y
1707 +CONFIG_HID_APPLE=y
1708 +CONFIG_HID_BELKIN=y
1709 +CONFIG_HID_CHERRY=y
1710 +CONFIG_HID_CHICONY=y
1711 +CONFIG_HID_CYPRESS=y
1712 +CONFIG_HID_EZKEY=y
1713 +CONFIG_HID_ITE=y
1714 +CONFIG_HID_KENSINGTON=y
1715 +CONFIG_HID_LOGITECH=y
1716 +CONFIG_HID_REDRAGON=y
1717 +CONFIG_HID_MICROSOFT=y
1718 +CONFIG_HID_MONTEREY=y
1719 +CONFIG_HID_MULTITOUCH=m
1720 +CONFIG_I2C_HID_ACPI=m
1721 +CONFIG_I2C_HID_OF=m
1722 +CONFIG_USB_CONN_GPIO=y
1723 +CONFIG_USB=y
1724 +CONFIG_USB_OTG=y
1725 +CONFIG_USB_XHCI_HCD=y
1726 +CONFIG_USB_XHCI_PCI_RENESAS=m
1727 +CONFIG_USB_EHCI_HCD=y
1728 +CONFIG_USB_EHCI_HCD_PLATFORM=y
1729 +CONFIG_USB_OHCI_HCD=y
1730 +CONFIG_USB_OHCI_HCD_PLATFORM=y
1731 +CONFIG_USB_HCD_TEST_MODE=y
1732 +CONFIG_USB_ACM=y
1733 +CONFIG_USB_STORAGE=y
1734 +CONFIG_USB_UAS=y
1735 +CONFIG_USB_CDNS_SUPPORT=y
1736 +CONFIG_USB_CDNS3=y
1737 +CONFIG_USB_CDNS3_GADGET=y
1738 +CONFIG_USB_CDNS3_HOST=y
1739 +CONFIG_USB_MUSB_HDRC=y
1740 +CONFIG_USB_DWC3=y
1741 +CONFIG_USB_DWC2=y
1742 +CONFIG_USB_CHIPIDEA=y
1743 +CONFIG_USB_CHIPIDEA_UDC=y
1744 +CONFIG_USB_CHIPIDEA_HOST=y
1745 +CONFIG_USB_ISP1760=y
1746 +CONFIG_USB_SERIAL=y
1747 +CONFIG_USB_SERIAL_CONSOLE=y
1748 +CONFIG_USB_SERIAL_GENERIC=y
1749 +CONFIG_USB_SERIAL_SIMPLE=y
1750 +CONFIG_USB_SERIAL_CP210X=m
1751 +CONFIG_USB_SERIAL_FTDI_SIO=y
1752 +CONFIG_USB_SERIAL_QUALCOMM=y
1753 +CONFIG_USB_SERIAL_OPTION=y
1754 +CONFIG_USB_TEST=m
1755 +CONFIG_USB_EHSET_TEST_FIXTURE=y
1756 +CONFIG_USB_HSIC_USB3503=y
1757 +CONFIG_NOP_USB_XCEIV=y
1758 +CONFIG_USB_MXS_PHY=y
1759 +CONFIG_USB_ULPI=y
1760 +CONFIG_USB_GADGET=y
1761 +CONFIG_USB_SNP_UDC_PLAT=y
1762 +CONFIG_USB_BDC_UDC=y
1763 +CONFIG_USB_CONFIGFS=y
1764 +CONFIG_USB_CONFIGFS_SERIAL=y
1765 +CONFIG_USB_CONFIGFS_ACM=y
1766 +CONFIG_USB_CONFIGFS_OBEX=y
1767 +CONFIG_USB_CONFIGFS_NCM=y
1768 +CONFIG_USB_CONFIGFS_ECM=y
1769 +CONFIG_USB_CONFIGFS_ECM_SUBSET=y
1770 +CONFIG_USB_CONFIGFS_RNDIS=y
1771 +CONFIG_USB_CONFIGFS_EEM=y
1772 +CONFIG_USB_CONFIGFS_MASS_STORAGE=y
1773 +CONFIG_USB_CONFIGFS_F_LB_SS=y
1774 +CONFIG_USB_CONFIGFS_F_FS=y
1775 +CONFIG_USB_CONFIGFS_F_UAC1=y
1776 +CONFIG_USB_CONFIGFS_F_UAC1_LEGACY=y
1777 +CONFIG_USB_CONFIGFS_F_UAC2=y
1778 +CONFIG_USB_CONFIGFS_F_MIDI=y
1779 +CONFIG_USB_CONFIGFS_F_HID=y
1780 +CONFIG_USB_CONFIGFS_F_UVC=y
1781 +CONFIG_USB_ZERO=m
1782 +CONFIG_USB_AUDIO=m
1783 +CONFIG_USB_ETH=m
1784 +CONFIG_USB_MASS_STORAGE=m
1785 +CONFIG_USB_G_SERIAL=m
1786 +CONFIG_TYPEC=y
1787 +CONFIG_TYPEC_TCPM=y
1788 +CONFIG_TYPEC_TCPCI=y
1789 +CONFIG_TYPEC_FUSB302=m
1790 +CONFIG_TYPEC_TPS6598X=m
1791 +CONFIG_TYPEC_HD3SS3220=m
1792 +CONFIG_TYPEC_SWITCH_GPIO=y
1793 +CONFIG_MMC=y
1794 +CONFIG_MMC_BLOCK_MINORS=32
1795 +CONFIG_MMC_ARMMMCI=y
1796 +CONFIG_MMC_SDHCI=y
1797 +CONFIG_MMC_SDHCI_PLTFM=y
1798 +CONFIG_MMC_SDHCI_OF_ARASAN=y
1799 +CONFIG_MMC_SDHCI_OF_ESDHC=y
1800 +CONFIG_MMC_SDHCI_CADENCE=y
1801 +CONFIG_MMC_SDHCI_ESDHC_IMX=y
1802 +CONFIG_MMC_SDHCI_F_SDH30=y
1803 +CONFIG_MMC_SPI=y
1804 +CONFIG_MMC_DW=y
1805 +CONFIG_MMC_DW_EXYNOS=y
1806 +CONFIG_MMC_DW_HI3798CV200=y
1807 +CONFIG_MMC_DW_K3=y
1808 +CONFIG_MMC_MTK=y
1809 +CONFIG_MMC_SDHCI_XENON=y
1810 +CONFIG_MMC_SDHCI_AM654=y
1811 +CONFIG_NEW_LEDS=y
1812 +CONFIG_LEDS_CLASS=y
1813 +CONFIG_LEDS_LM3692X=m
1814 +CONFIG_LEDS_PCA9532=m
1815 +CONFIG_LEDS_GPIO=y
1816 +CONFIG_LEDS_PCA995X=m
1817 +CONFIG_LEDS_PWM=y
1818 +CONFIG_LEDS_SYSCON=y
1819 +CONFIG_LEDS_TRIGGER_TIMER=y
1820 +CONFIG_LEDS_TRIGGER_DISK=y
1821 +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
1822 +CONFIG_LEDS_TRIGGER_CPU=y
1823 +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
1824 +CONFIG_LEDS_TRIGGER_PANIC=y
1825 +CONFIG_RTC_CLASS=y
1826 +CONFIG_RTC_DRV_DS1307=m
1827 +CONFIG_RTC_DRV_HYM8563=m
1828 +CONFIG_RTC_DRV_MAX77686=y
1829 +CONFIG_RTC_DRV_RK808=m
1830 +CONFIG_RTC_DRV_PCF85363=m
1831 +CONFIG_RTC_DRV_M41T80=m
1832 +CONFIG_RTC_DRV_RX8581=m
1833 +CONFIG_RTC_DRV_RV3028=m
1834 +CONFIG_RTC_DRV_RV8803=m
1835 +CONFIG_RTC_DRV_S5M=y
1836 +CONFIG_RTC_DRV_DS3232=y
1837 +CONFIG_RTC_DRV_PCF2127=m
1838 +CONFIG_RTC_DRV_EFI=y
1839 +CONFIG_RTC_DRV_CROS_EC=y
1840 +CONFIG_RTC_DRV_FSL_FTM_ALARM=m
1841 +CONFIG_RTC_DRV_PL031=y
1842 +CONFIG_RTC_DRV_SNVS=y
1843 +CONFIG_RTC_DRV_BBNSM=y
1844 +CONFIG_RTC_DRV_IMX_SC=y
1845 +CONFIG_RTC_DRV_IMX_RPMSG=y
1846 +CONFIG_DMADEVICES=y
1847 +CONFIG_BCM_SBA_RAID=m
1848 +CONFIG_FSL_EDMA=y
1849 +CONFIG_FSL_QDMA=m
1850 +CONFIG_FSL_EDMA_V3=y
1851 +CONFIG_IMX_SDMA=y
1852 +CONFIG_MV_XOR_V2=y
1853 +CONFIG_MXS_DMA=y
1854 +CONFIG_MXC_PXP_V3=y
1855 +CONFIG_PL330_DMA=y
1856 +CONFIG_QCOM_HIDMA_MGMT=y
1857 +CONFIG_QCOM_HIDMA=y
1858 +CONFIG_FSL_DPAA2_QDMA=m
1859 +CONFIG_DMATEST=y
1860 +CONFIG_DMABUF_HEAPS=y
1861 +CONFIG_DMABUF_HEAPS_SYSTEM=y
1862 +CONFIG_DMABUF_HEAPS_CMA=y
1863 +CONFIG_DMABUF_HEAPS_DSP=y
1864 +CONFIG_VFIO=y
1865 +CONFIG_VFIO_FSL_MC=y
1866 +CONFIG_VIRTIO_BALLOON=y
1867 +CONFIG_VIRTIO_MMIO=y
1868 +CONFIG_XEN_GNTDEV=y
1869 +CONFIG_XEN_GRANT_DEV_ALLOC=y
1870 +CONFIG_STAGING=y
1871 +CONFIG_STAGING_MEDIA=y
1872 +CONFIG_VIDEO_HANTRO=m
1873 +CONFIG_VIDEO_IMX_CAPTURE=y
1874 +CONFIG_IMX8_MEDIA_DEVICE=m
1875 +CONFIG_MHDP_HDMIRX=y
1876 +CONFIG_MHDP_HDMIRX_CEC=y
1877 +CONFIG_FSL_DPAA2=y
1878 +CONFIG_FSL_PPFE=y
1879 +CONFIG_FSL_PPFE_UTIL_DISABLED=y
1880 +CONFIG_ETHOSU=y
1881 +CONFIG_CHROME_PLATFORMS=y
1882 +CONFIG_CROS_EC=y
1883 +CONFIG_CROS_EC_I2C=y
1884 +CONFIG_CROS_EC_SPI=y
1885 +CONFIG_CROS_EC_CHARDEV=m
1886 +CONFIG_CLK_VEXPRESS_OSC=y
1887 +CONFIG_COMMON_CLK_RK808=y
1888 +CONFIG_COMMON_CLK_SCMI=y
1889 +CONFIG_COMMON_CLK_SCPI=y
1890 +CONFIG_COMMON_CLK_CS2000_CP=y
1891 +CONFIG_COMMON_CLK_FSL_SAI=y
1892 +CONFIG_COMMON_CLK_S2MPS11=y
1893 +CONFIG_COMMON_CLK_XGENE=y
1894 +CONFIG_COMMON_CLK_PWM=y
1895 +CONFIG_COMMON_CLK_VC5=y
1896 +CONFIG_CLK_IMX8MM=y
1897 +CONFIG_CLK_IMX8MN=y
1898 +CONFIG_CLK_IMX8MP=y
1899 +CONFIG_CLK_IMX8MQ=y
1900 +CONFIG_CLK_IMX8QXP=y
1901 +CONFIG_CLK_IMX8ULP=y
1902 +CONFIG_CLK_IMX93=y
1903 +CONFIG_HWSPINLOCK=y
1904 +CONFIG_ARM_MHU=y
1905 +CONFIG_IMX_MBOX=y
1906 +CONFIG_PLATFORM_MHU=y
1907 +CONFIG_IOMMU_IO_PGTABLE_ARMV7S=y
1908 +CONFIG_ARM_SMMU=y
1909 +CONFIG_ARM_SMMU_V3=y
1910 +CONFIG_REMOTEPROC=y
1911 +CONFIG_IMX_REMOTEPROC=y
1912 +CONFIG_IMX_DSP_REMOTEPROC=m
1913 +CONFIG_RPMSG_CHAR=m
1914 +CONFIG_RPMSG_QCOM_GLINK_RPM=y
1915 +CONFIG_SOUNDWIRE=m
1916 +CONFIG_SOUNDWIRE_QCOM=m
1917 +CONFIG_SOC_BRCMSTB=y
1918 +CONFIG_FSL_DPAA=y
1919 +CONFIG_FSL_MC_DPIO=y
1920 +CONFIG_FSL_RCPM=y
1921 +CONFIG_FSL_QIXIS=y
1922 +CONFIG_SOC_TI=y
1923 +CONFIG_EXTCON_PTN5150=m
1924 +CONFIG_EXTCON_USB_GPIO=y
1925 +CONFIG_EXTCON_USBC_CROS_EC=y
1926 +CONFIG_IIO=y
1927 +CONFIG_FXLS8962AF_I2C=m
1928 +CONFIG_IMX8QXP_ADC=y
1929 +CONFIG_IMX93_ADC=y
1930 +CONFIG_MAX9611=m
1931 +CONFIG_QCOM_SPMI_VADC=m
1932 +CONFIG_QCOM_SPMI_ADC5=m
1933 +CONFIG_IIO_CROS_EC_SENSORS_CORE=m
1934 +CONFIG_IIO_CROS_EC_SENSORS=m
1935 +CONFIG_FXAS21002C=y
1936 +CONFIG_FXOS8700_I2C=y
1937 +CONFIG_RPMSG_IIO_PEDOMETER=m
1938 +CONFIG_IIO_ST_LSM6DSX=y
1939 +CONFIG_IIO_CROS_EC_LIGHT_PROX=m
1940 +CONFIG_SENSORS_ISL29018=y
1941 +CONFIG_VCNL4000=m
1942 +CONFIG_IIO_ST_MAGN_3AXIS=m
1943 +CONFIG_IIO_CROS_EC_BARO=m
1944 +CONFIG_MPL3115=y
1945 +CONFIG_PWM=y
1946 +CONFIG_PWM_ADP5585=y
1947 +CONFIG_PWM_CROS_EC=m
1948 +CONFIG_PWM_FSL_FTM=m
1949 +CONFIG_PWM_IMX27=y
1950 +CONFIG_PWM_RPCHIP=y
1951 +CONFIG_PWM_SL28CPLD=m
1952 +CONFIG_SL28CPLD_INTC=y
1953 +CONFIG_RESET_IMX7=y
1954 +CONFIG_RESET_IMX8ULP_SIM=y
1955 +CONFIG_PHY_XGENE=y
1956 +CONFIG_PHY_MIXEL_LVDS=y
1957 +CONFIG_PHY_MIXEL_LVDS_COMBO=y
1958 +CONFIG_PHY_CADENCE_SALVO=y
1959 +CONFIG_PHY_FSL_IMX8MP_LVDS=y
1960 +CONFIG_PHY_FSL_IMX93_MIPI_DPHY=y
1961 +CONFIG_PHY_MIXEL_MIPI_DPHY=y
1962 +CONFIG_PHY_SAMSUNG_HDMI_PHY=y
1963 +CONFIG_PHY_QCOM_USB_HS=y
1964 +CONFIG_PHY_SAMSUNG_USB2=y
1965 +CONFIG_ARM_SMMU_V3_PMU=m
1966 +CONFIG_FSL_IMX8_DDR_PMU=y
1967 +CONFIG_FSL_IMX9_DDR_PMU=y
1968 +CONFIG_HISI_PMU=y
1969 +CONFIG_NVMEM_IMX_OCOTP=y
1970 +CONFIG_NVMEM_IMX_OCOTP_SCU=y
1971 +CONFIG_NVMEM_RMEM=m
1972 +CONFIG_FPGA=y
1973 +CONFIG_FPGA_BRIDGE=m
1974 +CONFIG_ALTERA_FREEZE_BRIDGE=m
1975 +CONFIG_FPGA_REGION=m
1976 +CONFIG_OF_FPGA_REGION=m
1977 +CONFIG_TEE=y
1978 +CONFIG_OPTEE=y
1979 +CONFIG_MUX_MMIO=y
1980 +CONFIG_SLIM_QCOM_CTRL=m
1981 +CONFIG_MXC_SIM=y
1982 +CONFIG_MXC_EMVSIM=y
1983 +CONFIG_EXT2_FS=y
1984 +CONFIG_EXT3_FS=y
1985 +CONFIG_EXT4_FS_POSIX_ACL=y
1986 +CONFIG_BTRFS_FS=m
1987 +CONFIG_BTRFS_FS_POSIX_ACL=y
1988 +CONFIG_FANOTIFY=y
1989 +CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
1990 +CONFIG_QUOTA=y
1991 +CONFIG_AUTOFS4_FS=y
1992 +CONFIG_FUSE_FS=m
1993 +CONFIG_CUSE=m
1994 +CONFIG_OVERLAY_FS=m
1995 +CONFIG_VFAT_FS=y
1996 +CONFIG_TMPFS_POSIX_ACL=y
1997 +CONFIG_HUGETLBFS=y
1998 +CONFIG_EFIVAR_FS=y
1999 +CONFIG_JFFS2_FS=y
2000 +CONFIG_UBIFS_FS=y
2001 +CONFIG_SQUASHFS=y
2002 +CONFIG_SQUASHFS_XZ=y
2003 +CONFIG_NFS_FS=y
2004 +CONFIG_NFS_V4=y
2005 +CONFIG_NFS_V4_1=y
2006 +CONFIG_NFS_V4_2=y
2007 +CONFIG_ROOT_NFS=y
2008 +CONFIG_9P_FS=y
2009 +CONFIG_NLS_CODEPAGE_437=y
2010 +CONFIG_NLS_ISO8859_1=y
2011 +CONFIG_TRUSTED_KEYS=m
2012 +# CONFIG_TRUSTED_KEYS_TPM is not set
2013 +# CONFIG_TRUSTED_KEYS_TEE is not set
2014 +CONFIG_SECURITY=y
2015 +CONFIG_CRYPTO_USER=y
2016 +CONFIG_CRYPTO_TEST=m
2017 +CONFIG_CRYPTO_DH=m
2018 +CONFIG_CRYPTO_CURVE25519=m
2019 +CONFIG_CRYPTO_CHACHA20POLY1305=m
2020 +CONFIG_CRYPTO_ECHAINIV=y
2021 +CONFIG_CRYPTO_TLS=m
2022 +CONFIG_CRYPTO_CFB=m
2023 +CONFIG_CRYPTO_CTS=m
2024 +CONFIG_CRYPTO_LRW=m
2025 +CONFIG_CRYPTO_OFB=m
2026 +CONFIG_CRYPTO_PCBC=m
2027 +CONFIG_CRYPTO_XCBC=m
2028 +CONFIG_CRYPTO_VMAC=m
2029 +CONFIG_CRYPTO_MD4=m
2030 +CONFIG_CRYPTO_RMD160=m
2031 +CONFIG_CRYPTO_STREEBOG=m
2032 +CONFIG_CRYPTO_WP512=m
2033 +CONFIG_CRYPTO_ANUBIS=m
2034 +CONFIG_CRYPTO_ARC4=m
2035 +CONFIG_CRYPTO_BLOWFISH=m
2036 +CONFIG_CRYPTO_CAMELLIA=m
2037 +CONFIG_CRYPTO_CAST5=m
2038 +CONFIG_CRYPTO_CAST6=m
2039 +CONFIG_CRYPTO_FCRYPT=m
2040 +CONFIG_CRYPTO_KHAZAD=m
2041 +CONFIG_CRYPTO_SEED=m
2042 +CONFIG_CRYPTO_SERPENT=m
2043 +CONFIG_CRYPTO_TEA=m
2044 +CONFIG_CRYPTO_TWOFISH=m
2045 +CONFIG_CRYPTO_ANSI_CPRNG=y
2046 +CONFIG_CRYPTO_USER_API_HASH=m
2047 +CONFIG_CRYPTO_USER_API_SKCIPHER=m
2048 +CONFIG_CRYPTO_USER_API_RNG=m
2049 +CONFIG_CRYPTO_USER_API_AEAD=m
2050 +CONFIG_CRYPTO_DEV_FSL_CAAM_SECVIO=m
2051 +CONFIG_CRYPTO_DEV_FSL_CAAM=m
2052 +CONFIG_CRYPTO_DEV_FSL_CAAM_SM_TEST=m
2053 +CONFIG_CRYPTO_DEV_FSL_DPAA2_CAAM=m
2054 +CONFIG_CRYPTO_DEV_CCREE=m
2055 +CONFIG_CRYPTO_DEV_HISI_TRNG=m
2056 +CONFIG_CRYPTO_DEV_AMLOGIC_GXL=m
2057 +CONFIG_INDIRECT_PIO=y
2058 +CONFIG_CRC8=y
2059 +CONFIG_CMA_SIZE_MBYTES=32
2060 +CONFIG_IRQ_POLL=y
2061 +CONFIG_PRINTK_TIME=y
2062 +CONFIG_DEBUG_INFO=y
2063 +CONFIG_DEBUG_INFO_REDUCED=y
2064 +CONFIG_MAGIC_SYSRQ=y
2065 +CONFIG_DEBUG_FS=y
2066 +# CONFIG_SCHED_DEBUG is not set
2067 +# CONFIG_DEBUG_PREEMPT is not set
2068 +# CONFIG_FTRACE is not set
2069 +CONFIG_CORESIGHT=y
2070 +CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y
2071 +CONFIG_CORESIGHT_SOURCE_ETM4X=y
2072 +CONFIG_MEMTEST=y
2073 diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
2074 index 47e1a2a60..1dde096b7 100644
2075 --- a/drivers/gpu/drm/panel/panel-simple.c
2076 +++ b/drivers/gpu/drm/panel/panel-simple.c
2077 @@ -1234,6 +1234,31 @@ static const struct panel_desc auo_g101evn010 = {
2078      .connector_type = DRM_MODE_CONNECTOR_LVDS,
2079  };
2080  
2081 +/* add by datasheet*/
2082 +static const struct drm_display_mode auo_g101ean02_mode = {
2083 +    .clock = 74250,
2084 +    .hdisplay = 1280,
2085 +    .hsync_start = 1280 + 100,
2086 +    .hsync_end = 1280 + 100 + 20,
2087 +    .htotal = 1280 + 100 + 20 + 80,
2088 +    .vdisplay = 800,
2089 +    .vsync_start = 800 + 18,
2090 +    .vsync_end = 800 + 18 + 6,
2091 +    .vtotal = 800 + 18 + 6 + 12,
2092 +};
2093 +
2094 +static const struct panel_desc auo_g101ean02 = {
2095 +    .modes = &auo_g101ean02_mode,
2096 +    .num_modes = 1,
2097 +    .bpc = 8,
2098 +    .size = {
2099 +        .width = 228,
2100 +        .height = 148,
2101 +    },
2102 +    .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
2103 +    .connector_type = DRM_MODE_CONNECTOR_LVDS,
2104 +};
2105 +
2106  static const struct drm_display_mode auo_g104sn02_mode = {
2107      .clock = 40000,
2108      .hdisplay = 800,
2109 @@ -4583,6 +4608,9 @@ static const struct of_device_id platform_of_match[] = {
2110      }, {
2111          .compatible = "auo,g101evn010",
2112          .data = &auo_g101evn010,
2113 +    }, {
2114 +        .compatible = "auo,g101ean02",
2115 +        .data = &auo_g101ean02,
2116      }, {
2117          .compatible = "auo,g104sn02",
2118          .data = &auo_g104sn02,
2119 diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
2120 index 8939e5fbd..1b2430047 100644
2121 --- a/drivers/net/usb/Kconfig
2122 +++ b/drivers/net/usb/Kconfig
2123 @@ -644,4 +644,11 @@ config USB_RTL8153_ECM
2124        CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
2125        supported by r8152 driver.
2126  
2127 +config USB_GOBI_NET
2128 +    tristate"Gobi USB Net driver for Quectel module"
2129 +    help
2130 +    Support Quectelmodule.
2131 +    A modemmanager with support for GobiNet is recommended.
2132 +    Tocompile this driver as a module, choose M here: the module will be calledGobiNet.
2133 +
2134  endif # USB_NET_DRIVERS
2135 diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
2136 index 4964f7b32..e34d3d112 100644
2137 --- a/drivers/net/usb/Makefile
2138 +++ b/drivers/net/usb/Makefile
2139 @@ -37,8 +37,11 @@ obj-$(CONFIG_USB_NET_CX82310_ETH)    += cx82310_eth.o
2140  obj-$(CONFIG_USB_NET_CDC_NCM)    += cdc_ncm.o
2141  obj-$(CONFIG_USB_NET_HUAWEI_CDC_NCM)    += huawei_cdc_ncm.o
2142  obj-$(CONFIG_USB_VL600)        += lg-vl600.o
2143 +obj-$(CONFIG_USB_NET_QMI_WWAN)    += qmi_wwan_q.o
2144  obj-$(CONFIG_USB_NET_QMI_WWAN)    += qmi_wwan.o
2145  obj-$(CONFIG_USB_NET_CDC_MBIM)    += cdc_mbim.o
2146  obj-$(CONFIG_USB_NET_CH9200)    += ch9200.o
2147  obj-$(CONFIG_USB_NET_AQC111)    += aqc111.o
2148  obj-$(CONFIG_USB_RTL8153_ECM)    += r8153_ecm.o
2149 +# obj-$(CONFIG_USB_GOBI_NET) += GobiNet.o
2150 +# GobiNet-objs := qmap.o GobiUSBNet.o QMIDevice.o QMI.o 
2151 diff --git a/drivers/net/usb/qmi_wwan_q.c b/drivers/net/usb/qmi_wwan_q.c
2152 new file mode 100644
2153 index 000000000..5b9c9ac18
2154 --- /dev/null
2155 +++ b/drivers/net/usb/qmi_wwan_q.c
2156 @@ -0,0 +1,2577 @@
2157 +/*
2158 + * Copyright (c) 2012  Bjørn Mork <bjorn@mork.no>
2159 + *
2160 + * The probing code is heavily inspired by cdc_ether, which is:
2161 + * Copyright (C) 2003-2005 by David Brownell
2162 + * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync)
2163 + *
2164 + * This program is free software; you can redistribute it and/or
2165 + * modify it under the terms of the GNU General Public License
2166 + * version 2 as published by the Free Software Foundation.
2167 + */
2168 +
2169 +#include <linux/module.h>
2170 +#include <linux/version.h>
2171 +#include <linux/interrupt.h>
2172 +#include <linux/netdevice.h>
2173 +#include <linux/ethtool.h>
2174 +#include <linux/etherdevice.h>
2175 +#include <linux/time.h>
2176 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,16,0) //8b094cd03b4a3793220d8d8d86a173bfea8c285b
2177 +#include <linux/timekeeping.h>
2178 +#else
2179 +#define timespec64  timespec
2180 +#define ktime_get_ts64 ktime_get_ts
2181 +#define timespec64_sub timespec_sub
2182 +#endif
2183 +#include <net/arp.h>
2184 +#include <net/ip.h>
2185 +#include <net/ipv6.h>
2186 +#include <linux/mii.h>
2187 +#include <linux/usb.h>
2188 +#include <linux/usb/cdc.h>
2189 +#include <linux/usb/usbnet.h>
2190 +#include <linux/usb/cdc-wdm.h>
2191 +
2192 +#ifndef ETH_P_MAP
2193 +#define ETH_P_MAP 0xDA1A
2194 +#endif
2195 +
2196 +#if (ETH_P_MAP == 0x00F9)
2197 +#undef ETH_P_MAP
2198 +#define ETH_P_MAP 0xDA1A
2199 +#endif
2200 +
2201 +#ifndef ARPHRD_RAWIP
2202 +#define ARPHRD_RAWIP ARPHRD_NONE
2203 +#endif
2204 +
2205 +#ifdef CONFIG_PINCTRL_IPQ807x
2206 +#define CONFIG_QCA_NSS_DRV
2207 +//#define CONFIG_QCA_NSS_PACKET_FILTER
2208 +#endif
2209 +
2210 +#define _RMNET_NSS_H_
2211 +#define _RMENT_NSS_H_
2212 +struct rmnet_nss_cb {
2213 +        int (*nss_create)(struct net_device *dev);
2214 +        int (*nss_free)(struct net_device *dev);
2215 +        int (*nss_tx)(struct sk_buff *skb);
2216 +};
2217 +static struct rmnet_nss_cb __read_mostly *nss_cb = NULL;
2218 +#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018)
2219 +#ifdef CONFIG_RMNET_DATA
2220 +#define CONFIG_QCA_NSS_DRV
2221 +/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */
2222 +/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */
2223 +extern struct rmnet_nss_cb *rmnet_nss_callbacks __rcu __read_mostly;
2224 +#endif
2225 +#endif
2226 +
2227 +/* This driver supports wwan (3G/LTE/?) devices using a vendor
2228 + * specific management protocol called Qualcomm MSM Interface (QMI) -
2229 + * in addition to the more common AT commands over serial interface
2230 + * management
2231 + *
2232 + * QMI is wrapped in CDC, using CDC encapsulated commands on the
2233 + * control ("master") interface of a two-interface CDC Union
2234 + * resembling standard CDC ECM.  The devices do not use the control
2235 + * interface for any other CDC messages.  Most likely because the
2236 + * management protocol is used in place of the standard CDC
2237 + * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE
2238 + *
2239 + * Alternatively, control and data functions can be combined in a
2240 + * single USB interface.
2241 + *
2242 + * Handling a protocol like QMI is out of the scope for any driver.
2243 + * It is exported as a character device using the cdc-wdm driver as
2244 + * a subdriver, enabling userspace applications ("modem managers") to
2245 + * handle it.
2246 + *
2247 + * These devices may alternatively/additionally be configured using AT
2248 + * commands on a serial interface
2249 + */
2250 +#define VERSION_NUMBER "V1.2.2"
2251 +#define QUECTEL_WWAN_VERSION "Quectel_Linux&Android_QMI_WWAN_Driver_"VERSION_NUMBER
2252 +static const char driver_name[] = "qmi_wwan_q";
2253 +
2254 +/* driver specific data */
2255 +struct qmi_wwan_state {
2256 +    struct usb_driver *subdriver;
2257 +    atomic_t pmcount;
2258 +    unsigned long unused;
2259 +    struct usb_interface *control;
2260 +    struct usb_interface *data;
2261 +};
2262 +
2263 +/* default ethernet address used by the modem */
2264 +static const u8 default_modem_addr[ETH_ALEN] = {0x02, 0x50, 0xf3};
2265 +
2266 +#if 1 //Added by Quectel
2267 +/*
2268 +    Quectel_WCDMA&LTE_Linux_USB_Driver_User_Guide_V1.9.pdf
2269 +    5.6.    Test QMAP on GobiNet or QMI WWAN
2270 +    0 - no QMAP
2271 +    1 - QMAP (Aggregation protocol)
2272 +    X - QMAP (Multiplexing and Aggregation protocol)
2273 +*/
2274 +#define QUECTEL_WWAN_QMAP 4 //MAX is 7
2275 +
2276 +#if defined(QUECTEL_WWAN_QMAP)
2277 +#define QUECTEL_QMAP_MUX_ID 0x81
2278 +
2279 +static uint __read_mostly qmap_mode = 0;
2280 +module_param( qmap_mode, uint, S_IRUGO);
2281 +module_param_named( rx_qmap, qmap_mode, uint, S_IRUGO );
2282 +#endif
2283 +
2284 +#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) || defined(CONFIG_BRIDGE_LAN)
2285 +#define QUECTEL_BRIDGE_MODE
2286 +#endif
2287 +
2288 +#ifdef QUECTEL_BRIDGE_MODE
2289 +static uint __read_mostly bridge_mode = 0/*|BIT(1)*/;
2290 +module_param( bridge_mode, uint, S_IRUGO );
2291 +#endif
2292 +
2293 +#ifdef CONFIG_BRIDGE_LAN
2294 +static const u8 broadcast_mac_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2295 +#endif
2296 +
2297 +//#define QMI_NETDEV_ONE_CARD_MODE
2298 +static uint __read_mostly one_card_mode = 0;
2299 +
2300 +#if defined(QUECTEL_WWAN_QMAP)
2301 +#define QUECTEL_UL_DATA_AGG 1
2302 +
2303 +#if defined(QUECTEL_UL_DATA_AGG)
2304 +struct tx_agg_ctx {
2305 +    /* QMIWDS_ADMIN_SET_DATA_FORMAT_RESP TLV_0x17 and TLV_0x18 */
2306 +    uint ul_data_aggregation_max_datagrams; //UplinkDataAggregationMaxDatagramsTlv
2307 +    uint ul_data_aggregation_max_size; //UplinkDataAggregationMaxSizeTlv
2308 +    uint dl_minimum_padding; //0x1A
2309 +};
2310 +#endif
2311 +
2312 +typedef struct {
2313 +    unsigned int size;
2314 +    unsigned int rx_urb_size;
2315 +    unsigned int ep_type;
2316 +    unsigned int iface_id;
2317 +    unsigned int qmap_mode;
2318 +    unsigned int qmap_version;
2319 +    unsigned int dl_minimum_padding;
2320 +    char ifname[8][16];
2321 +    unsigned char mux_id[8];
2322 +} RMNET_INFO;
2323 +
2324 +typedef struct sQmiWwanQmap
2325 +{
2326 +    struct usbnet *mpNetDev;
2327 +    struct driver_info driver_info;
2328 +    atomic_t refcount;
2329 +    struct net_device *mpQmapNetDev[QUECTEL_WWAN_QMAP];
2330 +    uint link_state;
2331 +    uint qmap_mode;
2332 +    uint qmap_size;
2333 +    uint qmap_version;
2334 +
2335 +#if defined(QUECTEL_UL_DATA_AGG)
2336 +    struct tx_agg_ctx tx_ctx;
2337 +    struct tasklet_struct    txq;
2338 +    struct tasklet_struct usbnet_bh;
2339 +#endif
2340 +
2341 +#ifdef QUECTEL_BRIDGE_MODE
2342 +    uint bridge_mode;
2343 +    uint bridge_ipv4;
2344 +    unsigned char bridge_mac[ETH_ALEN];
2345 +#ifdef CONFIG_BRIDGE_LAN
2346 +    unsigned char bridge_self_mac[ETH_ALEN];
2347 +#endif
2348 +#endif
2349 +    uint use_rmnet_usb;
2350 +    RMNET_INFO rmnet_info;
2351 +} sQmiWwanQmap;
2352 +
2353 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,13,0) //8f84985fec10de64a6b4cdfea45f2b0ab8f07c78
2354 +#define MHI_NETDEV_STATUS64
2355 +#endif
2356 +struct qmap_priv {
2357 +    struct usbnet *dev;
2358 +    struct net_device *real_dev;
2359 +    struct net_device *self_dev;
2360 +    u8 offset_id;
2361 +    u8 mux_id;
2362 +    u8 qmap_version; // 5~v1, 9~v5
2363 +    u8 link_state;
2364 +
2365 +#if defined(MHI_NETDEV_STATUS64)
2366 +    struct pcpu_sw_netstats __percpu *stats64;
2367 +#endif
2368 +
2369 +    spinlock_t agg_lock;
2370 +    struct sk_buff *agg_skb;
2371 +    unsigned agg_count;
2372 +    struct timespec64 agg_time;
2373 +    struct hrtimer agg_hrtimer;
2374 +    struct work_struct agg_wq;
2375 +    
2376 +#ifdef QUECTEL_BRIDGE_MODE
2377 +    uint bridge_mode;
2378 +    uint bridge_ipv4;
2379 +    unsigned char bridge_mac[ETH_ALEN];
2380 +#ifdef CONFIG_BRIDGE_LAN
2381 +    unsigned char bridge_self_mac[ETH_ALEN];
2382 +#endif
2383 +#endif
2384 +    uint use_qca_nss;    
2385 +};
2386 +
2387 +struct qmap_hdr {
2388 +    u8 cd_rsvd_pad;
2389 +    u8 mux_id;
2390 +    u16 pkt_len;
2391 +} __packed;
2392 +
2393 +enum rmnet_map_v5_header_type {
2394 +    RMNET_MAP_HEADER_TYPE_UNKNOWN,
2395 +    RMNET_MAP_HEADER_TYPE_COALESCING = 0x1,
2396 +    RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD = 0x2,
2397 +    RMNET_MAP_HEADER_TYPE_ENUM_LENGTH
2398 +};
2399 +
2400 +/* Main QMAP header */
2401 +struct rmnet_map_header {
2402 +#if defined(__LITTLE_ENDIAN_BITFIELD)
2403 +    u8  pad_len:6;
2404 +    u8  next_hdr:1;
2405 +    u8  cd_bit:1;
2406 +#elif defined (__BIG_ENDIAN_BITFIELD)
2407 +    u8  cd_bit:1;
2408 +    u8  next_hdr:1;
2409 +    u8  pad_len:6;
2410 +#else
2411 +#error    "Please fix <asm/byteorder.h>"
2412 +#endif
2413 +    u8  mux_id;
2414 +    __be16 pkt_len;
2415 +}  __aligned(1);
2416 +
2417 +/* QMAP v5 headers */
2418 +struct rmnet_map_v5_csum_header {
2419 +#if defined(__LITTLE_ENDIAN_BITFIELD)
2420 +    u8  next_hdr:1;
2421 +    u8  header_type:7;
2422 +    u8  hw_reserved:7;
2423 +    u8  csum_valid_required:1;
2424 +#elif defined (__BIG_ENDIAN_BITFIELD)
2425 +    u8  header_type:7;
2426 +    u8  next_hdr:1;
2427 +    u8  csum_valid_required:1;
2428 +    u8  hw_reserved:7;
2429 +#else
2430 +#error    "Please fix <asm/byteorder.h>"
2431 +#endif
2432 +    __be16 reserved;
2433 +} __aligned(1);
2434 +
2435 +#ifdef QUECTEL_BRIDGE_MODE
2436 +static int is_qmap_netdev(const struct net_device *netdev);
2437 +#endif
2438 +#endif
2439 +
2440 +static const struct driver_info rmnet_usb_info;
2441 +
2442 +#ifdef QUECTEL_BRIDGE_MODE
2443 +static int bridge_arp_reply(struct net_device *net, struct sk_buff *skb, uint bridge_ipv4) {
2444 +    struct arphdr *parp;
2445 +    u8 *arpptr, *sha;
2446 +    u8  sip[4], tip[4], ipv4[4];
2447 +    struct sk_buff *reply = NULL;
2448 +
2449 +    ipv4[0]  = (bridge_ipv4 >> 24) & 0xFF;
2450 +    ipv4[1]  = (bridge_ipv4 >> 16) & 0xFF;
2451 +    ipv4[2]  = (bridge_ipv4 >> 8) & 0xFF;
2452 +    ipv4[3]  = (bridge_ipv4 >> 0) & 0xFF;
2453 +
2454 +    parp = arp_hdr(skb);
2455 +
2456 +    if (parp->ar_hrd == htons(ARPHRD_ETHER)  && parp->ar_pro == htons(ETH_P_IP)
2457 +        && parp->ar_op == htons(ARPOP_REQUEST) && parp->ar_hln == 6 && parp->ar_pln == 4) {
2458 +        arpptr = (u8 *)parp + sizeof(struct arphdr);
2459 +        sha = arpptr;
2460 +        arpptr += net->addr_len;    /* sha */
2461 +        memcpy(sip, arpptr, sizeof(sip));
2462 +        arpptr += sizeof(sip);
2463 +        arpptr += net->addr_len;    /* tha */
2464 +        memcpy(tip, arpptr, sizeof(tip));
2465 +
2466 +        pr_info("%s sip = %d.%d.%d.%d, tip=%d.%d.%d.%d, ipv4=%d.%d.%d.%d\n", netdev_name(net),
2467 +            sip[0], sip[1], sip[2], sip[3], tip[0], tip[1], tip[2], tip[3], ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
2468 +    //wwan0 sip = 10.151.137.255, tip=10.151.138.0, ipv4=10.151.137.255
2469 +        if (tip[0] == ipv4[0] && tip[1] == ipv4[1] && (tip[2]&0xFC) == (ipv4[2]&0xFC) && tip[3] != ipv4[3])
2470 +            reply = arp_create(ARPOP_REPLY, ETH_P_ARP, *((__be32 *)sip), net, *((__be32 *)tip), sha, default_modem_addr, sha);
2471 +
2472 +        if (reply) {
2473 +            skb_reset_mac_header(reply);
2474 +            __skb_pull(reply, skb_network_offset(reply));
2475 +            reply->ip_summed = CHECKSUM_UNNECESSARY;
2476 +            reply->pkt_type = PACKET_HOST;
2477 +
2478 +            netif_rx_ni(reply);
2479 +        }
2480 +        return 1;
2481 +    }
2482 +
2483 +    return 0;
2484 +}
2485 +
2486 +static struct sk_buff *bridge_mode_tx_fixup(struct net_device *net, struct sk_buff *skb, uint bridge_ipv4, unsigned char *bridge_mac) {
2487 +    struct ethhdr *ehdr;
2488 +    const struct iphdr *iph;
2489 +
2490 +    skb_reset_mac_header(skb);
2491 +    ehdr = eth_hdr(skb);
2492 +
2493 +    if (ehdr->h_proto == htons(ETH_P_ARP)) {
2494 +        if (bridge_ipv4)
2495 +            bridge_arp_reply(net, skb, bridge_ipv4);
2496 +        return NULL;
2497 +    }
2498 +
2499 +    iph = ip_hdr(skb);
2500 +    //DBG("iphdr: ");
2501 +    //PrintHex((void *)iph, sizeof(struct iphdr));
2502 +
2503 +// 1    0.000000000    0.0.0.0    255.255.255.255    DHCP    362    DHCP Request  - Transaction ID 0xe7643ad7
2504 +    if (ehdr->h_proto == htons(ETH_P_IP) && iph->protocol == IPPROTO_UDP && iph->saddr == 0x00000000 && iph->daddr == 0xFFFFFFFF) {
2505 +        //if (udp_hdr(skb)->dest == htons(67)) //DHCP Request
2506 +        {
2507 +            memcpy(bridge_mac, ehdr->h_source, ETH_ALEN);
2508 +            pr_info("%s PC Mac Address: %02x:%02x:%02x:%02x:%02x:%02x\n", netdev_name(net),
2509 +                bridge_mac[0], bridge_mac[1], bridge_mac[2], bridge_mac[3], bridge_mac[4], bridge_mac[5]);
2510 +        }
2511 +    }
2512 +    
2513 +#ifdef CONFIG_BRIDGE_LAN
2514 +    //bridge Lan IP 192.168.0.0
2515 +    if (ehdr->h_proto == htons(ETH_P_IP) && (iph->daddr & 0xFFFF) == 0xA8C0)
2516 +    {
2517 +        struct sk_buff *reply = skb_copy(skb, GFP_ATOMIC);
2518 +        ehdr = eth_hdr(reply);
2519 +        
2520 +        memcpy(ehdr->h_source, default_modem_addr, ETH_ALEN);
2521 +        if(is_qmap_netdev(net))
2522 +        {
2523 +            struct qmap_priv *priv = netdev_priv(net);
2524 +            memcpy(ehdr->h_dest, priv->bridge_self_mac, ETH_ALEN);
2525 +        }
2526 +        else
2527 +        {
2528 +            struct usbnet * usbnetdev = netdev_priv(net);
2529 +            struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2530 +            sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2531 +            memcpy(ehdr->h_dest, pQmapDev->bridge_self_mac, ETH_ALEN);
2532 +        }
2533 +        
2534 +        //pr_info("%s br rx pkt addr: %02x:%02x:%02x:%02x:%02x:%02x -> %02x:%02x:%02x:%02x:%02x:%02x\n", netdev_name(net),
2535 +        //    ehdr->h_source[0], ehdr->h_source[1], ehdr->h_source[2], ehdr->h_source[3], ehdr->h_source[4], ehdr->h_source[5],
2536 +        //    ehdr->h_dest[0], ehdr->h_dest[1], ehdr->h_dest[2], ehdr->h_dest[3], ehdr->h_dest[4], ehdr->h_dest[5]);
2537 +        
2538 +        skb_reset_mac_header(reply);
2539 +        __skb_pull(reply, skb_network_offset(reply));
2540 +        reply->ip_summed = CHECKSUM_UNNECESSARY;
2541 +        reply->pkt_type = PACKET_HOST;
2542 +        netif_rx_ni(reply);
2543 +        return NULL;
2544 +    }
2545 +#endif
2546 +
2547 +    if (memcmp(ehdr->h_source, bridge_mac, ETH_ALEN)) {
2548 +        return NULL;
2549 +    }
2550 +
2551 +    return skb;
2552 +}
2553 +
2554 +static void bridge_mode_rx_fixup(sQmiWwanQmap *pQmapDev, struct net_device *net, struct sk_buff *skb) {
2555 +    uint bridge_mode = 0;
2556 +    unsigned char *bridge_mac;
2557 +
2558 +    if (pQmapDev->qmap_mode > 1 || pQmapDev->use_rmnet_usb == 1) {
2559 +        struct qmap_priv *priv = netdev_priv(net);
2560 +        bridge_mode = priv->bridge_mode;
2561 +        bridge_mac = priv->bridge_mac;
2562 +    }
2563 +    else {
2564 +        bridge_mode = pQmapDev->bridge_mode;
2565 +        bridge_mac = pQmapDev->bridge_mac;
2566 +    }
2567 +
2568 +    if (bridge_mode)
2569 +        memcpy(eth_hdr(skb)->h_dest, bridge_mac, ETH_ALEN);
2570 +    else
2571 +        memcpy(eth_hdr(skb)->h_dest, net->dev_addr, ETH_ALEN);
2572 +}
2573 +#endif
2574 +
2575 +#if defined(QUECTEL_WWAN_QMAP)
2576 +static ssize_t qmap_mode_show(struct device *dev, struct device_attribute *attr, char *buf) {
2577 +    struct net_device *netdev = to_net_dev(dev);
2578 +    struct usbnet * usbnetdev = netdev_priv( netdev );
2579 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2580 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2581 +
2582 +    return snprintf(buf, PAGE_SIZE, "%d\n",  pQmapDev->qmap_mode);
2583 +}
2584 +
2585 +static DEVICE_ATTR(qmap_mode, S_IRUGO, qmap_mode_show, NULL);
2586 +
2587 +static ssize_t qmap_size_show(struct device *dev, struct device_attribute *attr, char *buf) {
2588 +    struct net_device *netdev = to_net_dev(dev);
2589 +    struct usbnet * usbnetdev = netdev_priv( netdev );
2590 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2591 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2592 +
2593 +    return snprintf(buf, PAGE_SIZE, "%u\n",  pQmapDev->qmap_size);
2594 +}
2595 +
2596 +static DEVICE_ATTR(qmap_size, S_IRUGO, qmap_size_show, NULL);
2597 +
2598 +static ssize_t link_state_show(struct device *dev, struct device_attribute *attr, char *buf) {
2599 +    struct net_device *netdev = to_net_dev(dev);
2600 +    struct usbnet * usbnetdev = netdev_priv( netdev );
2601 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2602 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2603 +
2604 +    return snprintf(buf, PAGE_SIZE, "0x%x\n",  pQmapDev->link_state);
2605 +}
2606 +
2607 +static ssize_t link_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) {
2608 +    struct net_device *netdev = to_net_dev(dev);
2609 +    struct usbnet * usbnetdev = netdev_priv( netdev );
2610 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2611 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2612 +    unsigned link_state = 0;
2613 +    unsigned old_link = pQmapDev->link_state;
2614 +    uint offset_id = 0;
2615 +
2616 +    link_state = simple_strtoul(buf, NULL, 0);
2617 +
2618 +    if (pQmapDev->qmap_mode == 1) {
2619 +        pQmapDev->link_state = !!link_state;
2620 +    }
2621 +    else if (pQmapDev->qmap_mode > 1) {
2622 +        offset_id = ((link_state&0x7F) - 1);
2623 +
2624 +        if (offset_id >= pQmapDev->qmap_mode) {
2625 +            dev_info(dev, "%s offset_id is %d. but qmap_mode is %d\n", __func__, offset_id, pQmapDev->qmap_mode);
2626 +            return count;
2627 +        }
2628 +
2629 +        if (link_state&0x80)
2630 +            pQmapDev->link_state &= ~(1 << offset_id);
2631 +        else
2632 +            pQmapDev->link_state |= (1 << offset_id);
2633 +    }
2634 +
2635 +    if (old_link != pQmapDev->link_state) {
2636 +        struct net_device *qmap_net = pQmapDev->mpQmapNetDev[offset_id];
2637 +
2638 +        if (usbnetdev->net->flags & IFF_UP) {
2639 +            if (pQmapDev->link_state) {
2640 +                netif_carrier_on(usbnetdev->net);
2641 +            }
2642 +        }
2643 +
2644 +        if (qmap_net && qmap_net != netdev) {
2645 +            struct qmap_priv *priv = netdev_priv(qmap_net);
2646 +
2647 +            priv->link_state = !!(pQmapDev->link_state & (1 << offset_id));
2648 +
2649 +            if (qmap_net->flags & IFF_UP) {
2650 +                if (priv->link_state) {
2651 +                    netif_carrier_on(qmap_net);
2652 +                    if (netif_queue_stopped(qmap_net) && !netif_queue_stopped(usbnetdev->net))
2653 +                        netif_wake_queue(qmap_net);
2654 +                }
2655 +                else {
2656 +                    netif_carrier_off(qmap_net);
2657 +                }
2658 +            }
2659 +        }
2660 +
2661 +        if (usbnetdev->net->flags & IFF_UP) { 
2662 +            if (!pQmapDev->link_state) {
2663 +                netif_carrier_off(usbnetdev->net);
2664 +            }
2665 +        }
2666 +
2667 +        dev_info(dev, "link_state 0x%x -> 0x%x\n", old_link, pQmapDev->link_state);
2668 +    }
2669 +
2670 +    return count;
2671 +}
2672 +
2673 +#ifdef QUECTEL_BRIDGE_MODE
2674 +static ssize_t bridge_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) {
2675 +    struct net_device *netdev = to_net_dev(dev);
2676 +    uint old_mode = 0;
2677 +    uint bridge_mode = simple_strtoul(buf, NULL, 0);
2678 +
2679 +    if (netdev->type != ARPHRD_ETHER) {
2680 +        return count;
2681 +    }
2682 +
2683 +    if (is_qmap_netdev(netdev)) {
2684 +        struct qmap_priv *priv = netdev_priv(netdev);
2685 +        old_mode = priv->bridge_mode;
2686 +        priv->bridge_mode = bridge_mode;
2687 +    }
2688 +    else {
2689 +        struct usbnet * usbnetdev = netdev_priv( netdev );
2690 +        struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2691 +        sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2692 +        old_mode = pQmapDev->bridge_mode;
2693 +        pQmapDev->bridge_mode = bridge_mode;
2694 +    }
2695 +
2696 +    if (old_mode != bridge_mode) {
2697 +        dev_info(dev, "bridge_mode change to 0x%x\n", bridge_mode);
2698 +    }
2699 +
2700 +    return count;
2701 +}
2702 +
2703 +static ssize_t bridge_mode_show(struct device *dev, struct device_attribute *attr, char *buf) {
2704 +    struct net_device *netdev = to_net_dev(dev);
2705 +    uint bridge_mode = 0;
2706 +
2707 +    if (is_qmap_netdev(netdev)) {
2708 +        struct qmap_priv *priv = netdev_priv(netdev);
2709 +        bridge_mode = priv->bridge_mode;
2710 +    }
2711 +    else {
2712 +        struct usbnet * usbnetdev = netdev_priv( netdev );
2713 +        struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2714 +        sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2715 +        bridge_mode = pQmapDev->bridge_mode;
2716 +    }
2717 +
2718 +    return snprintf(buf, PAGE_SIZE, "%u\n", bridge_mode);
2719 +}
2720 +
2721 +static ssize_t bridge_ipv4_show(struct device *dev, struct device_attribute *attr, char *buf) {
2722 +    struct net_device *netdev = to_net_dev(dev);
2723 +    unsigned int bridge_ipv4 = 0;
2724 +    unsigned char ipv4[4];
2725 +
2726 +    if (is_qmap_netdev(netdev)) {
2727 +        struct qmap_priv *priv = netdev_priv(netdev);
2728 +        bridge_ipv4 = priv->bridge_ipv4;
2729 +    }
2730 +    else {
2731 +        struct usbnet * usbnetdev = netdev_priv( netdev );
2732 +        struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2733 +        sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2734 +        bridge_ipv4 = pQmapDev->bridge_ipv4;
2735 +    }
2736 +
2737 +    ipv4[0]  = (bridge_ipv4 >> 24) & 0xFF;
2738 +    ipv4[1]  = (bridge_ipv4 >> 16) & 0xFF;
2739 +    ipv4[2]  = (bridge_ipv4 >> 8) & 0xFF;
2740 +    ipv4[3]  = (bridge_ipv4 >> 0) & 0xFF;
2741 +
2742 +    return snprintf(buf, PAGE_SIZE, "%d.%d.%d.%d\n",  ipv4[0], ipv4[1], ipv4[2], ipv4[3]);
2743 +}
2744 +
2745 +static ssize_t bridge_ipv4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) {
2746 +    struct net_device *netdev = to_net_dev(dev);
2747 +
2748 +    if (is_qmap_netdev(netdev)) {
2749 +        struct qmap_priv *priv = netdev_priv(netdev);
2750 +        priv->bridge_ipv4 = simple_strtoul(buf, NULL, 16);
2751 +    }
2752 +    else {
2753 +        struct usbnet * usbnetdev = netdev_priv( netdev );
2754 +        struct qmi_wwan_state *info = (void *)&usbnetdev->data;
2755 +        sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
2756 +        pQmapDev->bridge_ipv4 = simple_strtoul(buf, NULL, 16);
2757 +    }
2758 +
2759 +    return count;
2760 +}
2761 +#endif
2762 +
2763 +static DEVICE_ATTR(link_state, S_IWUSR | S_IRUGO, link_state_show, link_state_store);
2764 +#ifdef QUECTEL_BRIDGE_MODE
2765 +static DEVICE_ATTR(bridge_mode, S_IWUSR | S_IRUGO, bridge_mode_show, bridge_mode_store);
2766 +static DEVICE_ATTR(bridge_ipv4, S_IWUSR | S_IRUGO, bridge_ipv4_show, bridge_ipv4_store);
2767 +#endif
2768 +
2769 +static struct attribute *qmi_wwan_sysfs_attrs[] = {
2770 +    &dev_attr_link_state.attr,
2771 +    &dev_attr_qmap_mode.attr,
2772 +    &dev_attr_qmap_size.attr,
2773 +#ifdef QUECTEL_BRIDGE_MODE
2774 +    &dev_attr_bridge_mode.attr,
2775 +    &dev_attr_bridge_ipv4.attr,
2776 +#endif
2777 +    NULL,
2778 +};
2779 +
2780 +static struct attribute_group qmi_wwan_sysfs_attr_group = {
2781 +    .attrs = qmi_wwan_sysfs_attrs,
2782 +};
2783 +
2784 +#ifdef QUECTEL_BRIDGE_MODE
2785 +static struct attribute *qmi_qmap_sysfs_attrs[] = {
2786 +    &dev_attr_bridge_mode.attr,
2787 +    &dev_attr_bridge_ipv4.attr,
2788 +    NULL,
2789 +};
2790 +
2791 +static struct attribute_group qmi_qmap_sysfs_attr_group = {
2792 +    .attrs = qmi_qmap_sysfs_attrs,
2793 +};
2794 +#endif
2795 +
2796 +static int qmap_open(struct net_device *qmap_net)
2797 +{
2798 +    struct qmap_priv *priv = netdev_priv(qmap_net);
2799 +    struct net_device *real_dev = priv->real_dev;
2800 +
2801 +    //printk("%s %s real_dev %d %d %d %d+++\n", __func__, dev->name,
2802 +    //    netif_carrier_ok(real_dev), netif_queue_stopped(real_dev), netif_carrier_ok(dev), netif_queue_stopped(dev));
2803 +
2804 +    if (!(priv->real_dev->flags & IFF_UP))
2805 +        return -ENETDOWN;
2806 +
2807 +    if (priv->link_state) {
2808 +        netif_carrier_on(real_dev);
2809 +        netif_carrier_on(qmap_net);
2810 +        if (netif_queue_stopped(qmap_net) && !netif_queue_stopped(real_dev))
2811 +            netif_wake_queue(qmap_net);
2812 +    }
2813 +    //printk("%s %s real_dev %d %d %d %d---\n", __func__, dev->name,
2814 +    //    netif_carrier_ok(real_dev), netif_queue_stopped(real_dev), netif_carrier_ok(dev), netif_queue_stopped(dev));
2815 +
2816 +    return 0;
2817 +}
2818 +
2819 +static int qmap_stop(struct net_device *qmap_net)
2820 +{
2821 +    //printk("%s %s %d %d+++\n", __func__, dev->name,
2822 +    //   netif_carrier_ok(dev), netif_queue_stopped(dev));
2823 +
2824 +    netif_carrier_off(qmap_net);
2825 +    return 0;
2826 +}
2827 +
2828 +static void qmap_wake_queue(sQmiWwanQmap *pQmapDev)
2829 +{
2830 +    uint i = 0;
2831 +
2832 +    if (!pQmapDev || !pQmapDev->use_rmnet_usb)
2833 +        return;
2834 +        
2835 +    for (i = 0; i < pQmapDev->qmap_mode; i++) {
2836 +        struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i];
2837 +
2838 +        if (qmap_net && netif_carrier_ok(qmap_net) && netif_queue_stopped(qmap_net)) {
2839 +            netif_wake_queue(qmap_net);
2840 +        }
2841 +    }
2842 +}
2843 +
2844 +static struct sk_buff * add_qhdr(struct sk_buff *skb, u8 mux_id) {
2845 +    struct qmap_hdr *qhdr;
2846 +    int pad = 0;
2847 +
2848 +    pad = skb->len%4;
2849 +    if (pad) {
2850 +        pad = 4 - pad;
2851 +        if (skb_tailroom(skb) < pad) {
2852 +            printk("skb_tailroom small!\n");
2853 +            pad = 0;
2854 +        }
2855 +        if (pad)
2856 +            __skb_put(skb, pad);
2857 +    }
2858 +                    
2859 +    qhdr = (struct qmap_hdr *)skb_push(skb, sizeof(struct qmap_hdr));
2860 +    qhdr->cd_rsvd_pad = pad;
2861 +    qhdr->mux_id = mux_id;
2862 +    qhdr->pkt_len = cpu_to_be16(skb->len - sizeof(struct qmap_hdr));
2863 +
2864 +    return skb;
2865 +}
2866 +
2867 +static struct sk_buff * add_qhdr_v5(struct sk_buff *skb, u8 mux_id) {
2868 +    struct rmnet_map_header *map_header;
2869 +    struct rmnet_map_v5_csum_header *ul_header;
2870 +    u32 padding, map_datalen;
2871 +
2872 +    map_datalen = skb->len;
2873 +    padding = map_datalen%4;
2874 +    if (padding) {
2875 +        padding = 4 - padding;
2876 +        if (skb_tailroom(skb) < padding) {
2877 +            printk("skb_tailroom small!\n");
2878 +            padding = 0;
2879 +        }
2880 +        if (padding)
2881 +            __skb_put(skb, padding);
2882 +    }
2883 +                    
2884 +    map_header = (struct rmnet_map_header *)skb_push(skb, (sizeof(struct rmnet_map_header) + sizeof(struct rmnet_map_v5_csum_header)));
2885 +    map_header->cd_bit = 0;
2886 +    map_header->next_hdr = 1;
2887 +    map_header->pad_len = padding;
2888 +    map_header->mux_id = mux_id;
2889 +    map_header->pkt_len = htons(map_datalen + padding);
2890 +
2891 +    ul_header = (struct rmnet_map_v5_csum_header *)(map_header + 1);
2892 +    memset(ul_header, 0, sizeof(*ul_header));
2893 +    ul_header->header_type = RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD;
2894 +    if (skb->ip_summed == CHECKSUM_PARTIAL) {
2895 +#if 0 //TODO
2896 +        skb->ip_summed = CHECKSUM_NONE;
2897 +        /* Ask for checksum offloading */
2898 +        ul_header->csum_valid_required = 1;
2899 +#endif
2900 +    }
2901 +
2902 +    return skb;
2903 +}
2904 +
2905 +static void rmnet_vnd_update_rx_stats(struct net_device *net,
2906 +            unsigned rx_packets, unsigned rx_bytes) {
2907 +#if defined(MHI_NETDEV_STATUS64)
2908 +    struct qmap_priv *dev = netdev_priv(net);
2909 +    struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
2910 +
2911 +    u64_stats_update_begin(&stats64->syncp);
2912 +    stats64->rx_packets += rx_packets;
2913 +    stats64->rx_bytes += rx_bytes;
2914 +    u64_stats_update_end(&stats64->syncp);
2915 +#else
2916 +    net->stats.rx_packets += rx_packets;
2917 +    net->stats.rx_bytes += rx_bytes;
2918 +#endif
2919 +}
2920 +
2921 +static void rmnet_vnd_update_tx_stats(struct net_device *net,
2922 +            unsigned tx_packets, unsigned tx_bytes) {    
2923 +#if defined(MHI_NETDEV_STATUS64)
2924 +    struct qmap_priv *dev = netdev_priv(net);
2925 +    struct pcpu_sw_netstats *stats64 = this_cpu_ptr(dev->stats64);
2926 +
2927 +    u64_stats_update_begin(&stats64->syncp);
2928 +    stats64->tx_packets += tx_packets;
2929 +    stats64->tx_bytes += tx_bytes;
2930 +    u64_stats_update_end(&stats64->syncp);
2931 +#else
2932 +    net->stats.tx_packets += tx_packets;
2933 +    net->stats.tx_bytes += tx_bytes;
2934 +#endif
2935 +}
2936 +
2937 +#if defined(MHI_NETDEV_STATUS64)
2938 +static struct rtnl_link_stats64 *_rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats)
2939 +{
2940 +    struct qmap_priv *dev = netdev_priv(net);
2941 +    unsigned int start;
2942 +    int cpu;
2943 +
2944 +    netdev_stats_to_stats64(stats, &net->stats);
2945 +
2946 +    if (nss_cb && dev->use_qca_nss) { // rmnet_nss.c:rmnet_nss_tx() will update rx stats
2947 +        stats->rx_packets = 0;
2948 +        stats->rx_bytes = 0;
2949 +    }
2950 +
2951 +    for_each_possible_cpu(cpu) {
2952 +        struct pcpu_sw_netstats *stats64;
2953 +        u64 rx_packets, rx_bytes;
2954 +        u64 tx_packets, tx_bytes;
2955 +
2956 +        stats64 = per_cpu_ptr(dev->stats64, cpu);
2957 +
2958 +        do {
2959 +            start = u64_stats_fetch_begin_irq(&stats64->syncp);
2960 +            rx_packets = stats64->rx_packets;
2961 +            rx_bytes = stats64->rx_bytes;
2962 +            tx_packets = stats64->tx_packets;
2963 +            tx_bytes = stats64->tx_bytes;
2964 +        } while (u64_stats_fetch_retry_irq(&stats64->syncp, start));
2965 +
2966 +        stats->rx_packets += rx_packets;
2967 +        stats->rx_bytes += rx_bytes;
2968 +        stats->tx_packets += tx_packets;
2969 +        stats->tx_bytes += tx_bytes;
2970 +    }
2971 +
2972 +    return stats;
2973 +}
2974 +
2975 +#if (LINUX_VERSION_CODE > KERNEL_VERSION( 4,10,0 )) //bc1f44709cf27fb2a5766cadafe7e2ad5e9cb221
2976 +static void rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) {
2977 +    _rmnet_vnd_get_stats64(net, stats);
2978 +}
2979 +#else
2980 +static struct rtnl_link_stats64 *rmnet_vnd_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) {
2981 +    return _rmnet_vnd_get_stats64(net, stats);
2982 +}
2983 +#endif
2984 +#endif
2985 +
2986 +#if defined(QUECTEL_UL_DATA_AGG)
2987 +static void usbnet_bh(unsigned long data) {
2988 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)data;
2989 +    struct tasklet_struct *t = &pQmapDev->usbnet_bh;
2990 +    bool use_callback = false;
2991 +
2992 +#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,8,0 )) //c955e329bb9d44fab75cf2116542fcc0de0473c5
2993 +    use_callback = t->use_callback;
2994 +    if (use_callback)
2995 +        t->callback(&pQmapDev->mpNetDev->bh);
2996 +#endif
2997 +
2998 +    if (!use_callback)
2999 +        t->func(t->data);
3000 +
3001 +    if (!netif_queue_stopped(pQmapDev->mpNetDev->net)) {
3002 +        qmap_wake_queue((sQmiWwanQmap *)data);
3003 +    }
3004 +}
3005 +
3006 +static void rmnet_usb_tx_wake_queue(unsigned long data) {
3007 +    qmap_wake_queue((sQmiWwanQmap *)data);
3008 +}
3009 +
3010 +#if 0
3011 +static void rmnet_usb_tx_skb_destructor(struct sk_buff *skb) {
3012 +    struct net_device    *net = skb->dev;
3013 +    struct usbnet * dev = netdev_priv( net );
3014 +    struct qmi_wwan_state *info = (void *)&dev->data;
3015 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3016 +
3017 +    if (pQmapDev && pQmapDev->use_rmnet_usb) {
3018 +        int i;
3019 +        
3020 +        for (i = 0; i < pQmapDev->qmap_mode; i++) {
3021 +            struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i];
3022 +
3023 +            if (qmap_net && netif_carrier_ok(qmap_net) && netif_queue_stopped(qmap_net)) {
3024 +                tasklet_schedule(&pQmapDev->txq);
3025 +                break;
3026 +            }
3027 +        }
3028 +    }
3029 +}
3030 +#endif
3031 +
3032 +static int rmnet_usb_tx_agg_skip(struct sk_buff *skb, int offset)
3033 +{
3034 +    u8 *packet_start = skb->data + offset;
3035 +    int ready2send = 0;
3036 +
3037 +    if (skb->protocol == htons(ETH_P_IP)) {
3038 +        struct iphdr *ip4h = (struct iphdr *)(packet_start);
3039 +
3040 +        if (ip4h->protocol == IPPROTO_TCP) {
3041 +            const struct tcphdr *th = (const struct tcphdr *)(packet_start + sizeof(struct iphdr));
3042 +            if (th->psh) {
3043 +                ready2send = 1;
3044 +            }
3045 +        }
3046 +        else if (ip4h->protocol == IPPROTO_ICMP)
3047 +            ready2send = 1;
3048 +
3049 +    } else if (skb->protocol == htons(ETH_P_IPV6)) {
3050 +        struct ipv6hdr *ip6h = (struct ipv6hdr *)(packet_start);
3051 +
3052 +        if (ip6h->nexthdr == NEXTHDR_TCP) {
3053 +            const struct tcphdr *th = (const struct tcphdr *)(packet_start + sizeof(struct ipv6hdr));
3054 +            if (th->psh) {
3055 +                ready2send = 1;
3056 +            }
3057 +        } else if (ip6h->nexthdr == NEXTHDR_ICMP) {
3058 +            ready2send = 1;
3059 +        } else if (ip6h->nexthdr == NEXTHDR_FRAGMENT) {
3060 +            struct frag_hdr *frag;
3061 +
3062 +            frag = (struct frag_hdr *)(packet_start
3063 +                           + sizeof(struct ipv6hdr));
3064 +            if (frag->nexthdr == IPPROTO_ICMPV6)
3065 +                ready2send = 1;
3066 +        }
3067 +    }
3068 +
3069 +    return ready2send;
3070 +}
3071 +
3072 +static void rmnet_usb_tx_agg_work(struct work_struct *work)
3073 +{
3074 +    struct qmap_priv *priv =
3075 +            container_of(work, struct qmap_priv, agg_wq);
3076 +    struct sk_buff *skb = NULL;
3077 +    unsigned long flags;
3078 +
3079 +    spin_lock_irqsave(&priv->agg_lock, flags);
3080 +    if (likely(priv->agg_skb)) {
3081 +        skb = priv->agg_skb;
3082 +        priv->agg_skb = NULL;
3083 +        priv->agg_count = 0;
3084 +        skb->protocol = htons(ETH_P_MAP);
3085 +        skb->dev = priv->real_dev;
3086 +        ktime_get_ts64(&priv->agg_time);
3087 +    }
3088 +    spin_unlock_irqrestore(&priv->agg_lock, flags);
3089 +    
3090 +    if (skb) {
3091 +        int err;
3092 +#if 0
3093 +        if (!skb->destructor)
3094 +            skb->destructor = rmnet_usb_tx_skb_destructor;
3095 +#endif
3096 +        err = dev_queue_xmit(skb);
3097 +        if (err != NET_XMIT_SUCCESS) {
3098 +            priv->self_dev->stats.tx_errors++;
3099 +        }
3100 +    }
3101 +}
3102 +
3103 +static enum hrtimer_restart  rmnet_usb_tx_agg_timer_cb(struct hrtimer *timer)
3104 +{
3105 +    struct qmap_priv *priv =
3106 +            container_of(timer, struct qmap_priv, agg_hrtimer);
3107 +
3108 +    schedule_work(&priv->agg_wq);
3109 +    return HRTIMER_NORESTART;
3110 +}
3111 +
3112 +static long agg_time_limit __read_mostly = 1000000L; //reduce this time, can get better TPUT performance, but will increase USB interrupts
3113 +module_param(agg_time_limit, long, S_IRUGO | S_IWUSR);
3114 +MODULE_PARM_DESC(agg_time_limit, "Maximum time packets sit in the agg buf");
3115 +
3116 +static long agg_bypass_time __read_mostly = 10000000L;
3117 +module_param(agg_bypass_time, long, S_IRUGO | S_IWUSR);
3118 +MODULE_PARM_DESC(agg_bypass_time, "Skip agg when apart spaced more than this");
3119 +
3120 +static int rmnet_usb_tx_agg(struct sk_buff *skb, struct qmap_priv *priv) {
3121 +    struct qmi_wwan_state *info = (void *)&priv->dev->data;
3122 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3123 +    struct tx_agg_ctx *ctx = &pQmapDev->tx_ctx;
3124 +    int ready2send = 0;
3125 +    int xmit_more = 0;
3126 +    struct timespec64 diff, now;
3127 +    struct sk_buff *agg_skb = NULL;
3128 +    unsigned long flags;
3129 +    int err;
3130 +    struct net_device *pNet = priv->self_dev;
3131 +
3132 +#if LINUX_VERSION_CODE < KERNEL_VERSION(5,1,0) //6b16f9ee89b8d5709f24bc3ac89ae8b5452c0d7c
3133 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,16,0)
3134 +    xmit_more = skb->xmit_more;
3135 +#endif
3136 +#else
3137 +    xmit_more = netdev_xmit_more();
3138 +#endif
3139 +
3140 +    rmnet_vnd_update_tx_stats(pNet, 1, skb->len);
3141 +
3142 +    if (ctx->ul_data_aggregation_max_datagrams == 1) {
3143 +        skb->protocol = htons(ETH_P_MAP);
3144 +        skb->dev = priv->real_dev;
3145 +#if 0
3146 +        if (!skb->destructor)
3147 +            skb->destructor = rmnet_usb_tx_skb_destructor;
3148 +#endif
3149 +        err = dev_queue_xmit(skb);
3150 +        if (err != NET_XMIT_SUCCESS)        
3151 +            pNet->stats.tx_errors++;
3152 +        return NET_XMIT_SUCCESS;
3153 +    }
3154 +
3155 +new_packet:
3156 +    spin_lock_irqsave(&priv->agg_lock, flags);
3157 +    agg_skb = NULL;
3158 +    ready2send = 0;
3159 +    ktime_get_ts64(&now);
3160 +    diff = timespec64_sub(now, priv->agg_time);
3161 +
3162 +    if (priv->agg_skb) {
3163 +        if ((priv->agg_skb->len + skb->len) < ctx->ul_data_aggregation_max_size) {
3164 +            memcpy(skb_put(priv->agg_skb, skb->len), skb->data, skb->len);
3165 +            priv->agg_count++;
3166 +
3167 +            if (diff.tv_sec > 0 || diff.tv_nsec > agg_time_limit) {
3168 +                ready2send = 1;
3169 +            }
3170 +            else if (priv->agg_count == ctx->ul_data_aggregation_max_datagrams) {
3171 +                ready2send = 1;
3172 +            }
3173 +            else if (xmit_more == 0) {
3174 +                struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb->data;
3175 +                size_t offset = sizeof(struct rmnet_map_header);
3176 +                if (map_header->next_hdr)
3177 +                    offset += sizeof(struct rmnet_map_v5_csum_header);
3178 +
3179 +                ready2send = rmnet_usb_tx_agg_skip(skb, offset);
3180 +            }
3181 +            
3182 +            dev_kfree_skb_any(skb);
3183 +            skb = NULL;
3184 +        }
3185 +        else {
3186 +            ready2send = 1;
3187 +        }
3188 +
3189 +        if (ready2send) {
3190 +            agg_skb = priv->agg_skb;
3191 +            priv->agg_skb = NULL;
3192 +            priv->agg_count = 0;
3193 +        }
3194 +    }
3195 +    else if (skb) {
3196 +        if (diff.tv_sec > 0 || diff.tv_nsec > agg_bypass_time) {
3197 +            ready2send = 1;
3198 +        }
3199 +        else if (xmit_more == 0) {
3200 +            struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb->data;
3201 +            size_t offset = sizeof(struct rmnet_map_header);
3202 +            if (map_header->next_hdr)
3203 +                offset += sizeof(struct rmnet_map_v5_csum_header);
3204 +
3205 +            ready2send = rmnet_usb_tx_agg_skip(skb, offset);
3206 +        }
3207 +
3208 +        if (ready2send == 0) {
3209 +            priv->agg_skb = alloc_skb(ctx->ul_data_aggregation_max_size, GFP_ATOMIC);
3210 +            if (priv->agg_skb) {
3211 +                skb_reset_network_header(priv->agg_skb); //protocol da1a is buggy, dev wwan0
3212 +                memcpy(skb_put(priv->agg_skb, skb->len), skb->data, skb->len);
3213 +                priv->agg_count++;
3214 +                dev_kfree_skb_any(skb);
3215 +                skb = NULL;
3216 +            }
3217 +            else {
3218 +                ready2send = 1;
3219 +            }
3220 +        }
3221 +
3222 +        if (ready2send) {
3223 +            agg_skb = skb;
3224 +            skb = NULL;
3225 +        }
3226 +    }
3227 +
3228 +    if (ready2send) {
3229 +        priv->agg_time = now;
3230 +    }
3231 +    spin_unlock_irqrestore(&priv->agg_lock, flags);
3232 +
3233 +    if (agg_skb) {
3234 +        agg_skb->protocol = htons(ETH_P_MAP);
3235 +        agg_skb->dev = priv->real_dev;
3236 +#if 0
3237 +        if (!agg_skb->destructor)
3238 +            agg_skb->destructor = rmnet_usb_tx_skb_destructor;
3239 +#endif
3240 +        err = dev_queue_xmit(agg_skb);
3241 +        if (err != NET_XMIT_SUCCESS) {
3242 +            pNet->stats.tx_errors++;
3243 +        }
3244 +    }
3245 +
3246 +    if (skb) {
3247 +        goto new_packet;
3248 +    }
3249 +
3250 +    if (priv->agg_skb) {
3251 +        if (!hrtimer_is_queued(&priv->agg_hrtimer))
3252 +            hrtimer_start(&priv->agg_hrtimer, ns_to_ktime(NSEC_PER_MSEC * 2), HRTIMER_MODE_REL);
3253 +    }
3254 +
3255 +    return NET_XMIT_SUCCESS;
3256 +}
3257 +#endif
3258 +
3259 +static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
3260 +                    struct net_device *pNet)
3261 +{
3262 +    int err;
3263 +    struct qmap_priv *priv = netdev_priv(pNet);
3264 +
3265 +    if (netif_queue_stopped(priv->real_dev)) {
3266 +        netif_stop_queue(pNet);
3267 +        return NETDEV_TX_BUSY;
3268 +    }
3269 +
3270 +    //printk("%s 1 skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
3271 +    if (pNet->type == ARPHRD_ETHER) {
3272 +        skb_reset_mac_header(skb);
3273 +
3274 +#ifdef QUECTEL_BRIDGE_MODE
3275 +        if (priv->bridge_mode && bridge_mode_tx_fixup(pNet, skb, priv->bridge_ipv4, priv->bridge_mac) == NULL) {
3276 +            dev_kfree_skb_any (skb);
3277 +            return NETDEV_TX_OK;
3278 +        }
3279 +#endif
3280 +
3281 +        if (skb_pull(skb, ETH_HLEN) == NULL) {
3282 +            dev_kfree_skb_any (skb);
3283 +            return NETDEV_TX_OK;
3284 +        }
3285 +    }
3286 +    //printk("%s 2 skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
3287 +
3288 +    if (priv->qmap_version == 5) {
3289 +        add_qhdr(skb, priv->mux_id);
3290 +    }
3291 +    else if (priv->qmap_version == 9) {
3292 +        add_qhdr_v5(skb, priv->mux_id);
3293 +    }
3294 +    else {
3295 +        dev_kfree_skb_any (skb);
3296 +        return NETDEV_TX_OK;
3297 +    }
3298 +    //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
3299 +
3300 +    err = rmnet_usb_tx_agg(skb, priv);
3301 +
3302 +    return err;
3303 +}
3304 +
3305 +static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu)
3306 +{
3307 +    if (new_mtu < 0)
3308 +        return -EINVAL;
3309 +
3310 +  if (new_mtu > 1500)
3311 +    printk("warning, set mtu greater than 1500, %d\n", new_mtu);
3312 +
3313 +    rmnet_dev->mtu = new_mtu;
3314 +    return 0;
3315 +}
3316 +
3317 +/* drivers may override default ethtool_ops in their bind() routine */
3318 +static const struct ethtool_ops rmnet_vnd_ethtool_ops = {
3319 +    .get_link        = ethtool_op_get_link,
3320 +};
3321 +
3322 +static const struct net_device_ops rmnet_vnd_ops = {
3323 +    .ndo_open       = qmap_open,
3324 +    .ndo_stop       = qmap_stop,
3325 +    .ndo_start_xmit = rmnet_vnd_start_xmit,
3326 +    .ndo_change_mtu = rmnet_vnd_change_mtu,
3327 +#if defined(MHI_NETDEV_STATUS64)
3328 +    .ndo_get_stats64    = rmnet_vnd_get_stats64,
3329 +#endif
3330 +};
3331 +
3332 +static void rmnet_usb_ether_setup(struct net_device *rmnet_dev)
3333 +{
3334 +    ether_setup(rmnet_dev);
3335 +
3336 +    rmnet_dev->flags |= IFF_NOARP;
3337 +    rmnet_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
3338 +
3339 +#if LINUX_VERSION_CODE > KERNEL_VERSION(4,10,0)
3340 +  rmnet_dev->max_mtu = 65535;
3341 +#endif
3342 +
3343 +    rmnet_dev->ethtool_ops = &rmnet_vnd_ethtool_ops;
3344 +    rmnet_dev->netdev_ops = &rmnet_vnd_ops;
3345 +}
3346 +
3347 +static void rmnet_usb_rawip_setup(struct net_device *rmnet_dev)
3348 +{
3349 +    rmnet_dev->needed_headroom = 16;
3350 +
3351 +    /* Raw IP mode */
3352 +    rmnet_dev->header_ops = NULL;  /* No header */
3353 +    rmnet_dev->type = ARPHRD_RAWIP;
3354 +    rmnet_dev->hard_header_len = 0;
3355 +    rmnet_dev->flags |= IFF_NOARP;
3356 +    rmnet_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
3357 +
3358 +    rmnet_dev->ethtool_ops = &rmnet_vnd_ethtool_ops;
3359 +    rmnet_dev->netdev_ops = &rmnet_vnd_ops;
3360 +}
3361 +
3362 +static rx_handler_result_t qca_nss_rx_handler(struct sk_buff **pskb)
3363 +{
3364 +    struct sk_buff *skb = *pskb;
3365 +
3366 +    if (!skb)
3367 +        return RX_HANDLER_CONSUMED;
3368 +    
3369 +    //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
3370 +
3371 +    if (skb->pkt_type == PACKET_LOOPBACK)
3372 +        return RX_HANDLER_PASS;
3373 +
3374 +    /* Check this so that we dont loop around netif_receive_skb */
3375 +    if (skb->cb[0] == 1) {
3376 +        skb->cb[0] = 0;
3377 +
3378 +        return RX_HANDLER_PASS;
3379 +    }
3380 +
3381 +    if (nss_cb) {
3382 +        nss_cb->nss_tx(skb);
3383 +        return RX_HANDLER_CONSUMED;
3384 +    }
3385 +
3386 +    return RX_HANDLER_PASS;
3387 +}
3388 +
3389 +static int qmap_register_device(sQmiWwanQmap * pDev, u8 offset_id)
3390 +{
3391 +    struct net_device *real_dev = pDev->mpNetDev->net;
3392 +    struct net_device *qmap_net;
3393 +    struct qmap_priv *priv;
3394 +    int err;
3395 +    char name[IFNAMSIZ];
3396 +    int use_qca_nss = !!nss_cb;
3397 +
3398 +    sprintf(name, "%s_%d", real_dev->name, offset_id + 1);
3399 +#ifdef NET_NAME_UNKNOWN
3400 +    qmap_net = alloc_netdev(sizeof(struct qmap_priv), name,
3401 +                NET_NAME_UNKNOWN, rmnet_usb_ether_setup);
3402 +#else
3403 +    qmap_net = alloc_netdev(sizeof(struct qmap_priv), name,
3404 +                rmnet_usb_ether_setup);
3405 +#endif
3406 +    if (!qmap_net)
3407 +        return -ENOBUFS;
3408 +
3409 +    SET_NETDEV_DEV(qmap_net, &real_dev->dev);
3410 +    priv = netdev_priv(qmap_net);
3411 +    priv->offset_id = offset_id;
3412 +    priv->real_dev = real_dev;
3413 +    priv->self_dev = qmap_net;
3414 +    priv->dev = pDev->mpNetDev;
3415 +    priv->qmap_version = pDev->qmap_version;
3416 +    priv->mux_id = QUECTEL_QMAP_MUX_ID + offset_id;
3417 +    memcpy (qmap_net->dev_addr, real_dev->dev_addr, ETH_ALEN);
3418 +
3419 +#ifdef QUECTEL_BRIDGE_MODE
3420 +    priv->bridge_mode = !!(pDev->bridge_mode & BIT(offset_id));
3421 +    qmap_net->sysfs_groups[0] = &qmi_qmap_sysfs_attr_group;
3422 +    if (priv->bridge_mode)
3423 +        use_qca_nss = 0;
3424 +#ifdef CONFIG_BRIDGE_LAN
3425 +    memcpy(priv->bridge_self_mac, broadcast_mac_addr, ETH_ALEN);
3426 +#endif
3427 +#endif
3428 +
3429 +    if (nss_cb && use_qca_nss) {
3430 +        rmnet_usb_rawip_setup(qmap_net);
3431 +    }
3432 +
3433 +    priv->agg_skb = NULL;
3434 +    priv->agg_count = 0;
3435 +    hrtimer_init(&priv->agg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
3436 +    priv->agg_hrtimer.function = rmnet_usb_tx_agg_timer_cb;
3437 +    INIT_WORK(&priv->agg_wq, rmnet_usb_tx_agg_work);
3438 +    ktime_get_ts64(&priv->agg_time);
3439 +    spin_lock_init(&priv->agg_lock);
3440 +    priv->use_qca_nss = 0;
3441 +
3442 +#if defined(MHI_NETDEV_STATUS64)
3443 +    priv->stats64 = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
3444 +    if (!priv->stats64) {
3445 +        err = -ENOBUFS;
3446 +        goto out_free_newdev;
3447 +    }
3448 +#endif
3449 +
3450 +    err = register_netdev(qmap_net);
3451 +    if (err)
3452 +        dev_info(&real_dev->dev, "%s(%s)=%d\n", __func__, qmap_net->name, err);
3453 +    if (err < 0)
3454 +        goto out_free_newdev;
3455 +    netif_device_attach (qmap_net);
3456 +    netif_carrier_off(qmap_net);
3457 +
3458 +    if (nss_cb && use_qca_nss) {
3459 +        int rc = nss_cb->nss_create(qmap_net);
3460 +        if (rc) {
3461 +            /* Log, but don't fail the device creation */
3462 +            netdev_err(qmap_net, "Device will not use NSS path: %d\n", rc);
3463 +        } else {
3464 +            priv->use_qca_nss = 1;
3465 +            netdev_info(qmap_net, "NSS context created\n");
3466 +            rtnl_lock();
3467 +            netdev_rx_handler_register(qmap_net, qca_nss_rx_handler, NULL);
3468 +            rtnl_unlock();            
3469 +        }
3470 +    }
3471 +
3472 +    strcpy(pDev->rmnet_info.ifname[offset_id], qmap_net->name);
3473 +    pDev->rmnet_info.mux_id[offset_id] = priv->mux_id;
3474 +
3475 +    pDev->mpQmapNetDev[offset_id] = qmap_net;
3476 +
3477 +    dev_info(&real_dev->dev, "%s %s\n", __func__, qmap_net->name);
3478 +
3479 +    return 0;
3480 +
3481 +out_free_newdev:
3482 +    free_netdev(qmap_net);
3483 +    return err;
3484 +}
3485 +
3486 +static void qmap_unregister_device(sQmiWwanQmap * pDev, u8 offset_id) {
3487 +    struct net_device *qmap_net = pDev->mpQmapNetDev[offset_id];
3488 +
3489 +    if (qmap_net != NULL && qmap_net != pDev->mpNetDev->net) {
3490 +        struct qmap_priv *priv = netdev_priv(qmap_net);
3491 +        unsigned long flags;
3492 +
3493 +        pr_info("qmap_unregister_device(%s)\n", qmap_net->name);
3494 +        pDev->mpQmapNetDev[offset_id] = NULL;
3495 +        netif_carrier_off( qmap_net );
3496 +        netif_stop_queue( qmap_net );
3497 +        
3498 +        hrtimer_cancel(&priv->agg_hrtimer);
3499 +        cancel_work_sync(&priv->agg_wq);
3500 +        spin_lock_irqsave(&priv->agg_lock, flags);
3501 +        if (priv->agg_skb) {
3502 +            kfree_skb(priv->agg_skb);
3503 +        }
3504 +        spin_unlock_irqrestore(&priv->agg_lock, flags);
3505 +
3506 +        if (nss_cb && priv->use_qca_nss) {
3507 +            rtnl_lock();
3508 +            netdev_rx_handler_unregister(qmap_net);
3509 +            rtnl_unlock();
3510 +            nss_cb->nss_free(qmap_net);
3511 +        }
3512 +
3513 +#if defined(MHI_NETDEV_STATUS64)
3514 +        free_percpu(priv->stats64);
3515 +#endif
3516 +        unregister_netdev (qmap_net);
3517 +        free_netdev(qmap_net);
3518 +    }
3519 +}
3520 +
3521 +typedef struct {
3522 +    unsigned int size;
3523 +    unsigned int rx_urb_size;
3524 +    unsigned int ep_type;
3525 +    unsigned int iface_id;
3526 +    unsigned int MuxId;
3527 +    unsigned int ul_data_aggregation_max_datagrams; //0x17
3528 +    unsigned int ul_data_aggregation_max_size ;//0x18
3529 +    unsigned int dl_minimum_padding; //0x1A
3530 +} QMAP_SETTING;
3531 +
3532 +#ifdef CONFIG_BRIDGE_LAN
3533 +typedef struct {
3534 +    u8 id;
3535 +    u8 brmac[ETH_ALEN];
3536 +} BRMAC_SETTING;
3537 +#endif
3538 +
3539 +int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) {
3540 +    struct net_device *netdev = to_net_dev(dev);
3541 +    struct usbnet * usbnetdev = netdev_priv( netdev );
3542 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
3543 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3544 +
3545 +    if (qmap_settings->size != size) {
3546 +        dev_err(dev, "ERROR: qmap_settings.size donot match!\n");
3547 +        return -EOPNOTSUPP;
3548 +    }
3549 +
3550 +#ifdef QUECTEL_UL_DATA_AGG
3551 +    netif_tx_lock_bh(netdev);
3552 +    if (pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams == 1 && qmap_settings->ul_data_aggregation_max_datagrams > 1) {
3553 +        pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams = qmap_settings->ul_data_aggregation_max_datagrams;
3554 +        pQmapDev->tx_ctx.ul_data_aggregation_max_size = qmap_settings->ul_data_aggregation_max_size;
3555 +        pQmapDev->tx_ctx.dl_minimum_padding = qmap_settings->dl_minimum_padding;
3556 +        dev_info(dev, "ul_data_aggregation_max_datagrams=%d, ul_data_aggregation_max_size=%d, dl_minimum_padding=%d\n",
3557 +            pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams,
3558 +            pQmapDev->tx_ctx.ul_data_aggregation_max_size,
3559 +            pQmapDev->tx_ctx.dl_minimum_padding);
3560 +    }
3561 +    netif_tx_unlock_bh(netdev);
3562 +    return 0;
3563 +#endif
3564 +
3565 +    return -EOPNOTSUPP;
3566 +}
3567 +
3568 +static int qmap_ndo_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) {
3569 +    struct usbnet * usbnetdev = netdev_priv( dev );
3570 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
3571 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3572 +    int rc = -EOPNOTSUPP;
3573 +    uint link_state = 0;
3574 +     QMAP_SETTING qmap_settings = {0};
3575 +#ifdef CONFIG_BRIDGE_LAN
3576 +     BRMAC_SETTING brmac_settings = {0};
3577 +#endif
3578
3579 +    switch (cmd) {
3580 +    case 0x89F1: //SIOCDEVPRIVATE
3581 +        rc = copy_from_user(&link_state, ifr->ifr_ifru.ifru_data, sizeof(link_state));
3582 +        if (!rc) {
3583 +            char buf[32];
3584 +            snprintf(buf, sizeof(buf), "%u", link_state);
3585 +            link_state_store(&dev->dev, NULL, buf, strlen(buf));
3586 +        }
3587 +    break;
3588 +
3589 +    case 0x89F2: //SIOCDEVPRIVATE
3590 +        rc = copy_from_user(&qmap_settings, ifr->ifr_ifru.ifru_data, sizeof(qmap_settings));
3591 +        if (!rc) {
3592 +            rc = qma_setting_store(&dev->dev, &qmap_settings, sizeof(qmap_settings));
3593 +        }
3594 +    break;
3595 +
3596 +    case 0x89F3: //SIOCDEVPRIVATE
3597 +        if (pQmapDev->use_rmnet_usb) {
3598 +            uint i;
3599 +
3600 +            for (i = 0; i < pQmapDev->qmap_mode; i++) {
3601 +                struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i];
3602 +
3603 +                if (!qmap_net)
3604 +                    break;
3605 +
3606 +                strcpy(pQmapDev->rmnet_info.ifname[i], qmap_net->name);
3607 +            }
3608 +            rc = copy_to_user(ifr->ifr_ifru.ifru_data, &pQmapDev->rmnet_info, sizeof(pQmapDev->rmnet_info));
3609 +        }
3610 +    break;
3611 +    
3612 +#ifdef CONFIG_BRIDGE_LAN
3613 +    case 0x89F4: //SIOCDEVPRIVATE
3614 +        rc = copy_from_user(&brmac_settings, ifr->ifr_ifru.ifru_data, sizeof(brmac_settings));
3615 +        if (pQmapDev->use_rmnet_usb && brmac_settings.id < qmap_mode) {
3616 +            struct net_device *qmap_net = pQmapDev->mpQmapNetDev[brmac_settings.id];
3617 +            struct qmap_priv *priv = netdev_priv(qmap_net);
3618 +            memcpy(priv->bridge_self_mac, brmac_settings.brmac, ETH_ALEN);
3619 +            pr_info("ioctl 0x89F4 change qmapnet bridge(%d) lan mac -> %02x:%02x:%02x:%02x:%02x:%02x\n", brmac_settings.id, priv->bridge_self_mac[0],
3620 +                priv->bridge_self_mac[1], priv->bridge_self_mac[2], priv->bridge_self_mac[3], priv->bridge_self_mac[4], priv->bridge_self_mac[5]);
3621 +        }
3622 +        else if (!pQmapDev->use_rmnet_usb && brmac_settings.id == 0) {
3623 +            memcpy(pQmapDev->bridge_self_mac, brmac_settings.brmac, ETH_ALEN);
3624 +            pr_info("ioctl 0x89F4 change usbnet bridge(%d) lan mac -> %02x:%02x:%02x:%02x:%02x:%02x\n", brmac_settings.id, pQmapDev->bridge_self_mac[0],
3625 +                pQmapDev->bridge_self_mac[1], pQmapDev->bridge_self_mac[2], pQmapDev->bridge_self_mac[3], pQmapDev->bridge_self_mac[4], pQmapDev->bridge_self_mac[5]);
3626 +        }
3627 +        else {
3628 +            pr_info("ioctl 0x89F4 change bridge(%d) lan mac -> error id\n", brmac_settings.id);
3629 +            rc = -1;
3630 +        }
3631 +    break;
3632 +#endif
3633 +
3634 +    default:
3635 +    break;
3636 +    }
3637 +
3638 +    return rc;
3639 +}
3640 +
3641 +#ifdef QUECTEL_BRIDGE_MODE
3642 +static int is_qmap_netdev(const struct net_device *netdev) {
3643 +    return netdev->netdev_ops == &rmnet_vnd_ops;
3644 +}
3645 +#endif
3646 +#endif
3647 +
3648 +static struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) {
3649 +    //MDM9x07,MDM9628,MDM9x40,SDX20,SDX24 only work on RAW IP mode
3650 +    if ((dev->driver_info->flags & FLAG_NOARP) == 0)
3651 +        return skb;
3652 +
3653 +    // Skip Ethernet header from message
3654 +    if (dev->net->hard_header_len == 0)
3655 +        return skb;
3656 +    else
3657 +        skb_reset_mac_header(skb);
3658 +
3659 +#ifdef QUECTEL_BRIDGE_MODE
3660 +{
3661 +    struct qmi_wwan_state *info = (void *)&dev->data;
3662 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3663 +
3664 +    if (pQmapDev->bridge_mode && bridge_mode_tx_fixup(dev->net, skb, pQmapDev->bridge_ipv4, pQmapDev->bridge_mac) == NULL) {
3665 +          dev_kfree_skb_any (skb);
3666 +          return NULL;
3667 +    }
3668 +}
3669 +#endif
3670 +
3671 +    if (skb_pull(skb, ETH_HLEN)) {
3672 +        return skb;
3673 +    } else {
3674 +        dev_err(&dev->intf->dev,  "Packet Dropped ");
3675 +    }
3676 +
3677 +    // Filter the packet out, release it
3678 +    dev_kfree_skb_any(skb);
3679 +    return NULL;
3680 +}
3681 +#endif
3682 +
3683 +/* Make up an ethernet header if the packet doesn't have one.
3684 + *
3685 + * A firmware bug common among several devices cause them to send raw
3686 + * IP packets under some circumstances.  There is no way for the
3687 + * driver/host to know when this will happen.  And even when the bug
3688 + * hits, some packets will still arrive with an intact header.
3689 + *
3690 + * The supported devices are only capably of sending IPv4, IPv6 and
3691 + * ARP packets on a point-to-point link. Any packet with an ethernet
3692 + * header will have either our address or a broadcast/multicast
3693 + * address as destination.  ARP packets will always have a header.
3694 + *
3695 + * This means that this function will reliably add the appropriate
3696 + * header iff necessary, provided our hardware address does not start
3697 + * with 4 or 6.
3698 + *
3699 + * Another common firmware bug results in all packets being addressed
3700 + * to 00:a0:c6:00:00:00 despite the host address being different.
3701 + * This function will also fixup such packets.
3702 + */
3703 +static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
3704 +{
3705 +    __be16 proto;
3706 +
3707 +    /* This check is no longer done by usbnet */
3708 +    if (skb->len < dev->net->hard_header_len)
3709 +        return 0;
3710 +
3711 +    switch (skb->data[0] & 0xf0) {
3712 +    case 0x40:
3713 +        proto = htons(ETH_P_IP);
3714 +        break;
3715 +    case 0x60:
3716 +        proto = htons(ETH_P_IPV6);
3717 +        break;
3718 +    case 0x00:
3719 +        if (is_multicast_ether_addr(skb->data))
3720 +            return 1;
3721 +        /* possibly bogus destination - rewrite just in case */
3722 +        skb_reset_mac_header(skb);
3723 +        goto fix_dest;
3724 +    default:
3725 +        /* pass along other packets without modifications */
3726 +        return 1;
3727 +    }
3728 +    if (skb_headroom(skb) < ETH_HLEN)
3729 +        return 0;
3730 +    skb_push(skb, ETH_HLEN);
3731 +    skb_reset_mac_header(skb);
3732 +    eth_hdr(skb)->h_proto = proto;
3733 +    memset(eth_hdr(skb)->h_source, 0, ETH_ALEN);
3734 +#if 1 //Added by Quectel
3735 +    //some kernel will drop ethernet packet which's souce mac is all zero
3736 +    memcpy(eth_hdr(skb)->h_source, default_modem_addr, ETH_ALEN);
3737 +#endif
3738 +
3739 +fix_dest:
3740 +#ifdef QUECTEL_BRIDGE_MODE
3741 +{
3742 +    struct qmi_wwan_state *info = (void *)&dev->data;
3743 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3744 +    bridge_mode_rx_fixup(pQmapDev, dev->net, skb);
3745 +}
3746 +#else
3747 +    memcpy(eth_hdr(skb)->h_dest, dev->net->dev_addr, ETH_ALEN);
3748 +#endif
3749 +
3750 +    return 1;
3751 +}
3752 +
3753 +#if defined(QUECTEL_WWAN_QMAP)
3754 +static struct sk_buff *qmap_qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) {
3755 +    struct qmi_wwan_state *info = (void *)&dev->data;
3756 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3757 +
3758 +    if (unlikely(pQmapDev == NULL)) {
3759 +        goto drop_skb;
3760 +    } else if (unlikely(pQmapDev->qmap_mode && !pQmapDev->link_state)) {
3761 +        dev_dbg(&dev->net->dev, "link_state 0x%x, drop skb, len = %u\n", pQmapDev->link_state, skb->len);
3762 +        goto drop_skb;
3763 +    } else if (pQmapDev->qmap_mode == 0) {
3764 +        skb = qmi_wwan_tx_fixup(dev, skb, flags);
3765 +    }
3766 +    else if (pQmapDev->qmap_mode > 1) {
3767 +        WARN_ON(1); //never reach here.
3768 +    }
3769 +    else {
3770 +        if (likely(skb)) {
3771 +            skb = qmi_wwan_tx_fixup(dev, skb, flags);
3772 +
3773 +            if (skb) {
3774 +                if(pQmapDev->qmap_version == 5)
3775 +                    add_qhdr(skb, QUECTEL_QMAP_MUX_ID);
3776 +                else
3777 +                    add_qhdr_v5(skb, QUECTEL_QMAP_MUX_ID);                
3778 +            }
3779 +            else {
3780 +                return NULL;
3781 +            }
3782 +        }
3783 +    }
3784 +
3785 +    return skb;
3786 +drop_skb:
3787 +    dev_kfree_skb_any (skb);
3788 +    return NULL;
3789 +}
3790 +
3791 +static void qmap_packet_decode(sQmiWwanQmap *pQmapDev,
3792 +    struct sk_buff *skb_in, struct sk_buff_head *skb_chain)
3793 +{
3794 +    struct device *dev = &pQmapDev->mpNetDev->net->dev;
3795 +    struct sk_buff *qmap_skb;
3796 +    uint dl_minimum_padding = 0;
3797 +
3798 +    if (pQmapDev->qmap_version == 9)
3799 +        dl_minimum_padding = pQmapDev->tx_ctx.dl_minimum_padding;
3800 +
3801 +    /* __skb_queue_head_init() do not call spin_lock_init(&list->lock),
3802 +        so should not call skb_queue_tail/queue later.  */
3803 +    __skb_queue_head_init(skb_chain);
3804 +
3805 +    while (skb_in->len > sizeof(struct qmap_hdr)) {
3806 +        struct rmnet_map_header *map_header = (struct rmnet_map_header *)skb_in->data;
3807 +        struct rmnet_map_v5_csum_header *ul_header = NULL;
3808 +        size_t hdr_size = sizeof(struct rmnet_map_header);    
3809 +        struct net_device *qmap_net;
3810 +        int pkt_len = ntohs(map_header->pkt_len);
3811 +        int skb_len;
3812 +        __be16 protocol;
3813 +        int mux_id;
3814 +        int skip_nss = 0;
3815 +
3816 +        if (map_header->next_hdr) {
3817 +            ul_header = (struct rmnet_map_v5_csum_header *)(map_header + 1);
3818 +            hdr_size += sizeof(struct rmnet_map_v5_csum_header);
3819 +        }
3820 +        
3821 +        skb_len = pkt_len - (map_header->pad_len&0x3F);
3822 +        skb_len -= dl_minimum_padding;
3823 +
3824 +        mux_id = map_header->mux_id - QUECTEL_QMAP_MUX_ID;
3825 +        if (mux_id >= pQmapDev->qmap_mode) {
3826 +            dev_info(dev, "drop qmap unknow mux_id %x\n", map_header->mux_id);
3827 +            goto error_pkt;
3828 +        }
3829 +
3830 +        qmap_net = pQmapDev->mpQmapNetDev[mux_id];
3831 +        if (qmap_net == NULL) {
3832 +            dev_info(dev, "drop qmap unknow mux_id %x\n", map_header->mux_id);
3833 +            goto skip_pkt;
3834 +        }
3835 +    
3836 +        if (skb_len > qmap_net->mtu) {
3837 +            dev_info(dev, "drop skb_len=%x larger than mtu=%d\n", skb_len, qmap_net->mtu);
3838 +            goto error_pkt;
3839 +        }
3840 +
3841 +        if (skb_in->len < (pkt_len + hdr_size)) {
3842 +            dev_info(dev, "drop qmap unknow pkt, len=%d, pkt_len=%d\n", skb_in->len, pkt_len);
3843 +            goto error_pkt;
3844 +        }
3845 +
3846 +        if (map_header->cd_bit) {
3847 +            dev_info(dev, "skip qmap command packet\n");
3848 +            goto skip_pkt;
3849 +        }
3850 +
3851 +        switch (skb_in->data[hdr_size] & 0xf0) {
3852 +            case 0x40:
3853 +#ifdef CONFIG_QCA_NSS_PACKET_FILTER
3854 +                {
3855 +                    struct iphdr *ip4h = (struct iphdr *)(&skb_in->data[hdr_size]);
3856 +                    if (ip4h->protocol == IPPROTO_ICMP) {
3857 +                        skip_nss = 1;
3858 +                    }
3859 +                }
3860 +#endif
3861 +                protocol = htons(ETH_P_IP);
3862 +            break;
3863 +            case 0x60:
3864 +#ifdef CONFIG_QCA_NSS_PACKET_FILTER
3865 +                {
3866 +                    struct ipv6hdr *ip6h = (struct ipv6hdr *)(&skb_in->data[hdr_size]);
3867 +                    if (ip6h->nexthdr == NEXTHDR_ICMP) {
3868 +                        skip_nss = 1;
3869 +                    }
3870 +                }
3871 +#endif
3872 +            protocol = htons(ETH_P_IPV6);
3873 +            break;
3874 +            default:
3875 +                dev_info(dev, "unknow skb->protocol %02x\n", skb_in->data[hdr_size]);
3876 +                goto error_pkt;
3877 +        }
3878 +        
3879 +        qmap_skb = netdev_alloc_skb(qmap_net, skb_len);
3880 +        if (qmap_skb) {
3881 +            skb_put(qmap_skb, skb_len);
3882 +            memcpy(qmap_skb->data, skb_in->data + hdr_size, skb_len);
3883 +        }
3884 +
3885 +        if (qmap_skb == NULL) {
3886 +            dev_info(dev, "fail to alloc skb, pkt_len = %d\n", skb_len);
3887 +            goto error_pkt;
3888 +        }
3889 +
3890 +        skb_reset_transport_header(qmap_skb);
3891 +        skb_reset_network_header(qmap_skb);
3892 +        qmap_skb->pkt_type = PACKET_HOST;
3893 +        skb_set_mac_header(qmap_skb, 0);
3894 +        qmap_skb->protocol = protocol;
3895 +
3896 +        if(skip_nss)
3897 +            qmap_skb->cb[0] = 1;
3898 +
3899 +        if (ul_header && ul_header->header_type == RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD
3900 +            && ul_header->csum_valid_required) {
3901 +#if 0 //TODO
3902 +            qmap_skb->ip_summed = CHECKSUM_UNNECESSARY;
3903 +#endif
3904 +        }
3905 +
3906 +        if (qmap_skb->dev->type == ARPHRD_ETHER) {
3907 +            skb_push(qmap_skb, ETH_HLEN);
3908 +            skb_reset_mac_header(qmap_skb);
3909 +            memcpy(eth_hdr(qmap_skb)->h_source, default_modem_addr, ETH_ALEN);
3910 +            memcpy(eth_hdr(qmap_skb)->h_dest, qmap_net->dev_addr, ETH_ALEN);
3911 +            eth_hdr(qmap_skb)->h_proto = protocol;
3912 +#ifdef QUECTEL_BRIDGE_MODE
3913 +            bridge_mode_rx_fixup(pQmapDev, qmap_net, qmap_skb);
3914 +#endif
3915 +        }
3916 +
3917 +        __skb_queue_tail(skb_chain, qmap_skb);
3918 +
3919 +skip_pkt:
3920 +        skb_pull(skb_in, pkt_len + hdr_size);
3921 +    }
3922 +
3923 +error_pkt:
3924 +    return;
3925 +}
3926 +
3927 +static int qmap_qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
3928 +{
3929 +    struct qmi_wwan_state *info = (void *)&dev->data;
3930 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3931 +    struct sk_buff *qmap_skb;
3932 +    struct sk_buff_head skb_chain;
3933 +        
3934 +    if (pQmapDev->qmap_mode == 0)
3935 +        return qmi_wwan_rx_fixup(dev, skb_in);
3936 +
3937 +    qmap_packet_decode(pQmapDev, skb_in, &skb_chain);
3938 +
3939 +    while ((qmap_skb = __skb_dequeue (&skb_chain))) {
3940 +        if (qmap_skb->dev != dev->net) {
3941 +            WARN_ON(1); //never reach here.
3942 +        }
3943 +        else {
3944 +            qmap_skb->protocol = 0;
3945 +            usbnet_skb_return(dev, qmap_skb);
3946 +        }
3947 +    }
3948 +
3949 +    return 0;
3950 +}
3951 +#endif
3952 +
3953 +/* very simplistic detection of IPv4 or IPv6 headers */
3954 +static bool possibly_iphdr(const char *data)
3955 +{
3956 +    return (data[0] & 0xd0) == 0x40;
3957 +}
3958 +
3959 +/* disallow addresses which may be confused with IP headers */
3960 +static int qmi_wwan_mac_addr(struct net_device *dev, void *p)
3961 +{
3962 +    int ret;
3963 +    struct sockaddr *addr = p;
3964 +
3965 +    ret = eth_prepare_mac_addr_change(dev, p);
3966 +    if (ret < 0)
3967 +        return ret;
3968 +    if (possibly_iphdr(addr->sa_data))
3969 +        return -EADDRNOTAVAIL;
3970 +    eth_commit_mac_addr_change(dev, p);
3971 +    return 0;
3972 +}
3973 +
3974 +#if (LINUX_VERSION_CODE > KERNEL_VERSION( 4,10,0 )) //bc1f44709cf27fb2a5766cadafe7e2ad5e9cb221
3975 +static void (*_usbnet_get_stats64)(struct net_device *net, struct rtnl_link_stats64 *stats);
3976 +
3977 +static void qmi_wwan_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) {
3978 +    if (_usbnet_get_stats64) ////c8b5d129ee293bcf972e7279ac996bb8a138505c
3979 +        return _usbnet_get_stats64(net, stats);
3980 +    
3981 +    netdev_stats_to_stats64(stats, &net->stats);
3982 +}
3983 +#else
3984 +static struct rtnl_link_stats64 * (*_usbnet_get_stats64)(struct net_device *net, struct rtnl_link_stats64 *stats);
3985 +
3986 +static struct rtnl_link_stats64 * qmi_wwan_get_stats64(struct net_device *net, struct rtnl_link_stats64 *stats) {
3987 +    if (_usbnet_get_stats64)
3988 +        return _usbnet_get_stats64(net, stats);
3989 +    
3990 +    netdev_stats_to_stats64(stats, &net->stats);
3991 +    return stats;
3992 +}
3993 +#endif
3994 +
3995 +static int qmi_wwan_open (struct net_device *net) {
3996 +    struct usbnet * usbnetdev = netdev_priv( net );
3997 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
3998 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
3999 +    int retval;
4000 +
4001 +    retval = usbnet_open(net);
4002 +
4003 +    if (!retval) {
4004 +        if (pQmapDev && pQmapDev->qmap_mode == 1) {
4005 +            if (pQmapDev->link_state)
4006 +                netif_carrier_on(net);
4007 +        }
4008 +    }
4009 +
4010 +    return retval;
4011 +}
4012 +
4013 +static netdev_tx_t qmi_wwan_start_xmit (struct sk_buff *skb,
4014 +                     struct net_device *net) 
4015 +{
4016 +    struct usbnet * usbnetdev = netdev_priv( net );
4017 +    struct qmi_wwan_state *info = (void *)&usbnetdev->data;
4018 +    sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
4019 +    int retval;
4020 +
4021 +    retval = usbnet_start_xmit(skb, net);
4022 +
4023 +    if (netif_queue_stopped(net) && pQmapDev && pQmapDev->use_rmnet_usb) {
4024 +        int i;
4025 +        
4026 +        for (i = 0; i < pQmapDev->qmap_mode; i++) {
4027 +            struct net_device *qmap_net = pQmapDev->mpQmapNetDev[i];
4028 +            if (qmap_net) {
4029 +                netif_stop_queue(qmap_net);
4030 +            }
4031 +        }
4032 +    }
4033 +
4034 +    return retval;
4035 +}
4036 +
4037 +#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,14,0 )) //b9067f5dc4a07c8e24e01a1b277c6722d91be39e
4038 +#define use_ndo_siocdevprivate
4039 +#endif
4040 +#ifdef use_ndo_siocdevprivate
4041 +static int qmap_ndo_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd) {
4042 +    return qmap_ndo_do_ioctl(dev, ifr, cmd);
4043 +}
4044 +#endif
4045 +
4046 +static const struct net_device_ops qmi_wwan_netdev_ops = {
4047 +    .ndo_open        = qmi_wwan_open,
4048 +    .ndo_stop        = usbnet_stop,
4049 +    .ndo_start_xmit        = qmi_wwan_start_xmit,
4050 +    .ndo_tx_timeout        = usbnet_tx_timeout,
4051 +    .ndo_change_mtu        = usbnet_change_mtu,
4052 +    .ndo_get_stats64    = qmi_wwan_get_stats64,
4053 +    .ndo_set_mac_address    = qmi_wwan_mac_addr,
4054 +    .ndo_validate_addr    = eth_validate_addr,
4055 +#if defined(QUECTEL_WWAN_QMAP)// && defined(CONFIG_ANDROID)
4056 +    .ndo_do_ioctl = qmap_ndo_do_ioctl,
4057 +#ifdef use_ndo_siocdevprivate
4058 +    .ndo_siocdevprivate = qmap_ndo_siocdevprivate,
4059 +#endif
4060 +#endif
4061 +};
4062 +
4063 +static void ql_net_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
4064 +{
4065 +    /* Inherit standard device info */
4066 +    usbnet_get_drvinfo(net, info);
4067 +    strlcpy(info->driver, driver_name, sizeof(info->driver));
4068 +    strlcpy(info->version, VERSION_NUMBER, sizeof(info->version));
4069 +}
4070 +
4071 +static struct ethtool_ops ql_net_ethtool_ops;
4072 +
4073 +/* using a counter to merge subdriver requests with our own into a
4074 + * combined state
4075 + */
4076 +static int qmi_wwan_manage_power(struct usbnet *dev, int on)
4077 +{
4078 +    struct qmi_wwan_state *info = (void *)&dev->data;
4079 +    int rv;
4080 +
4081 +    dev_dbg(&dev->intf->dev, "%s() pmcount=%d, on=%d\n", __func__,
4082 +        atomic_read(&info->pmcount), on);
4083 +
4084 +    if ((on && atomic_add_return(1, &info->pmcount) == 1) ||
4085 +        (!on && atomic_dec_and_test(&info->pmcount))) {
4086 +        /* need autopm_get/put here to ensure the usbcore sees
4087 +         * the new value
4088 +         */
4089 +        rv = usb_autopm_get_interface(dev->intf);
4090 +        dev->intf->needs_remote_wakeup = on;
4091 +        if (!rv)
4092 +            usb_autopm_put_interface(dev->intf);
4093 +    }
4094 +    return 0;
4095 +}
4096 +
4097 +static int qmi_wwan_cdc_wdm_manage_power(struct usb_interface *intf, int on)
4098 +{
4099 +    struct usbnet *dev = usb_get_intfdata(intf);
4100 +
4101 +    /* can be called while disconnecting */
4102 +    if (!dev)
4103 +        return 0;
4104 +    return qmi_wwan_manage_power(dev, on);
4105 +}
4106 +
4107 +/* collect all three endpoints and register subdriver */
4108 +static int qmi_wwan_register_subdriver(struct usbnet *dev)
4109 +{
4110 +    int rv;
4111 +    struct usb_driver *subdriver = NULL;
4112 +    struct qmi_wwan_state *info = (void *)&dev->data;
4113 +
4114 +    /* collect bulk endpoints */
4115 +    rv = usbnet_get_endpoints(dev, info->data);
4116 +    if (rv < 0)
4117 +        goto err;
4118 +
4119 +    /* update status endpoint if separate control interface */
4120 +    if (info->control != info->data)
4121 +        dev->status = &info->control->cur_altsetting->endpoint[0];
4122 +
4123 +    /* require interrupt endpoint for subdriver */
4124 +    if (!dev->status) {
4125 +        rv = -EINVAL;
4126 +        goto err;
4127 +    }
4128 +
4129 +    /* for subdriver power management */
4130 +    atomic_set(&info->pmcount, 0);
4131 +
4132 +    /* register subdriver */
4133 +#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,12,0 )) //cac6fb015f719104e60b1c68c15ca5b734f57b9c
4134 +    subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc,
4135 +                     4096, WWAN_PORT_QMI, &qmi_wwan_cdc_wdm_manage_power);
4136 +#else
4137 +    subdriver = usb_cdc_wdm_register(info->control, &dev->status->desc,
4138 +                     4096, &qmi_wwan_cdc_wdm_manage_power);
4139 +
4140 +#endif
4141 +    if (IS_ERR(subdriver)) {
4142 +        dev_err(&info->control->dev, "subdriver registration failed\n");
4143 +        rv = PTR_ERR(subdriver);
4144 +        goto err;
4145 +    }
4146 +
4147 +    /* prevent usbnet from using status endpoint */
4148 +    dev->status = NULL;
4149 +
4150 +    /* save subdriver struct for suspend/resume wrappers */
4151 +    info->subdriver = subdriver;
4152 +
4153 +err:
4154 +    return rv;
4155 +}
4156 +
4157 +static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
4158 +{
4159 +    int status = -1;
4160 +    struct usb_driver *driver = driver_of(intf);
4161 +    struct qmi_wwan_state *info = (void *)&dev->data;
4162 +
4163 +    BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) <
4164 +              sizeof(struct qmi_wwan_state)));
4165 +
4166 +    /* set up initial state */
4167 +    info->control = intf;
4168 +    info->data = intf;
4169 +
4170 +    status = qmi_wwan_register_subdriver(dev);
4171 +    if (status < 0 && info->control != info->data) {
4172 +        usb_set_intfdata(info->data, NULL);
4173 +        usb_driver_release_interface(driver, info->data);
4174 +    }
4175 +
4176 +    /* Never use the same address on both ends of the link, even
4177 +     * if the buggy firmware told us to.
4178 +     */
4179 +    if (ether_addr_equal(dev->net->dev_addr, default_modem_addr))
4180 +        eth_hw_addr_random(dev->net);
4181 +
4182 +    /* make MAC addr easily distinguishable from an IP header */
4183 +    if (possibly_iphdr(dev->net->dev_addr)) {
4184 +        dev->net->dev_addr[0] |= 0x02;    /* set local assignment bit */
4185 +        dev->net->dev_addr[0] &= 0xbf;    /* clear "IP" bit */
4186 +    }
4187 +    if (!_usbnet_get_stats64)
4188 +        _usbnet_get_stats64 = dev->net->netdev_ops->ndo_get_stats64;
4189 +    dev->net->netdev_ops = &qmi_wwan_netdev_ops;
4190 +
4191 +    ql_net_ethtool_ops = *dev->net->ethtool_ops;
4192 +    ql_net_ethtool_ops.get_drvinfo = ql_net_get_drvinfo;
4193 +    dev->net->ethtool_ops = &ql_net_ethtool_ops;
4194 +
4195 +#if 1 //Added by Quectel
4196 +    if (dev->driver_info->flags & FLAG_NOARP) {
4197 +        int ret;
4198 +        char buf[32] = "Module";
4199 +
4200 +        ret = usb_string(dev->udev, dev->udev->descriptor.iProduct, buf, sizeof(buf));
4201 +        if (ret > 0) {
4202 +            buf[ret] = '\0';
4203 +        }
4204 +
4205 +        dev_info(&intf->dev, "Quectel %s work on RawIP mode\n", buf);
4206 +        dev->net->flags |= IFF_NOARP;
4207 +        dev->net->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
4208 +
4209 +        usb_control_msg(
4210 +            interface_to_usbdev(intf),
4211 +            usb_sndctrlpipe(interface_to_usbdev(intf), 0),
4212 +            0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE
4213 +            0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
4214 +            1, //active CDC DTR
4215 +            intf->cur_altsetting->desc.bInterfaceNumber,
4216 +            NULL, 0, 100);
4217 +    }
4218 +
4219 +    //to advoid module report mtu 1460, but rx 1500 bytes IP packets, and cause the customer's system crash
4220 +    //next setting can make usbnet.c:usbnet_change_mtu() do not modify rx_urb_size according to hard mtu
4221 +    dev->rx_urb_size = ETH_DATA_LEN + ETH_HLEN + 6;
4222 +
4223 +#if defined(QUECTEL_WWAN_QMAP)
4224 +    if (qmap_mode > QUECTEL_WWAN_QMAP)
4225 +        qmap_mode = QUECTEL_WWAN_QMAP;
4226 +
4227 +    if (!status)
4228 +    {
4229 +        sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)kzalloc(sizeof(sQmiWwanQmap), GFP_KERNEL);
4230 +
4231 +        if (pQmapDev == NULL)
4232 +            return -ENODEV;
4233 +
4234 +#ifdef QUECTEL_BRIDGE_MODE
4235 +        pQmapDev->bridge_mode = bridge_mode;
4236 +#ifdef CONFIG_BRIDGE_LAN
4237 +        memcpy(pQmapDev->bridge_self_mac, broadcast_mac_addr, ETH_ALEN);
4238 +#endif
4239 +#endif
4240 +        pQmapDev->mpNetDev = dev;
4241 +        pQmapDev->link_state = 1;
4242 +        //on OpenWrt, if set rmnet_usb0.1 as WAN, '/sbin/netifd' will auto create VLAN for rmnet_usb0
4243 +        dev->net->features |= (NETIF_F_VLAN_CHALLENGED);
4244 +
4245 +        if (dev->driver_info->flags & FLAG_NOARP)
4246 +        {
4247 +            int qmap_version = (dev->driver_info->data>>8)&0xFF;
4248 +            int qmap_size = (dev->driver_info->data)&0xFF;
4249 +            int idProduct = le16_to_cpu(dev->udev->descriptor.idProduct);
4250 +            int lte_a = (idProduct == 0x0306 || idProduct == 0x030B || idProduct == 0x0512 || idProduct == 0x0620 || idProduct == 0x0800 || idProduct == 0x0801);
4251 +
4252 +            if (qmap_size > 4096 || dev->udev->speed >= USB_SPEED_SUPER) { //if meet this requirements, must be LTE-A or 5G
4253 +                lte_a = 1;
4254 +            }
4255 +            
4256 +            pQmapDev->qmap_mode = qmap_mode;
4257 +            if (lte_a && pQmapDev->qmap_mode == 0) {
4258 +                pQmapDev->qmap_mode = 1; //force use QMAP
4259 +                if(qmap_mode == 0)
4260 +                    qmap_mode = 1; //old quectel-CM only check sys/module/wwan0/parameters/qmap_mode
4261 +            }
4262 +
4263 +            if (pQmapDev->qmap_mode) {
4264 +                pQmapDev->qmap_version = qmap_version;
4265 +                pQmapDev->qmap_size = qmap_size*1024;
4266 +                dev->rx_urb_size = pQmapDev->qmap_size;
4267 +                //for these modules, if send packet before qmi_start_network, or cause host PC crash, or cause modules crash
4268 +                   pQmapDev->link_state = !lte_a;
4269 +
4270 +                if (pQmapDev->qmap_mode > 1)
4271 +                    pQmapDev->use_rmnet_usb = 1;
4272 +                else if (idProduct == 0x0800 || idProduct == 0x0801)
4273 +                    pQmapDev->use_rmnet_usb = 1; //benefit for ul data agg
4274 +#ifdef QMI_NETDEV_ONE_CARD_MODE
4275 +                if(pQmapDev->use_rmnet_usb == 1 && pQmapDev->qmap_mode == 1)
4276 +                    one_card_mode = 1;
4277 +                pQmapDev->rmnet_info.mux_id[0] = QUECTEL_QMAP_MUX_ID;
4278 +#endif    
4279 +                pQmapDev->rmnet_info.size = sizeof(RMNET_INFO);
4280 +                pQmapDev->rmnet_info.rx_urb_size = pQmapDev->qmap_size;
4281 +                pQmapDev->rmnet_info.ep_type = 2; //DATA_EP_TYPE_HSUSB
4282 +                pQmapDev->rmnet_info.iface_id = 4;
4283 +                pQmapDev->rmnet_info.qmap_mode = pQmapDev->qmap_mode;
4284 +                pQmapDev->rmnet_info.qmap_version = pQmapDev->qmap_version;
4285 +                pQmapDev->rmnet_info.dl_minimum_padding = 0;
4286 +
4287 +#if defined(QUECTEL_UL_DATA_AGG)
4288 +                pQmapDev->tx_ctx.ul_data_aggregation_max_datagrams = 1;
4289 +                pQmapDev->tx_ctx.ul_data_aggregation_max_size = 1500;
4290 +#endif
4291 +
4292 +                if (pQmapDev->use_rmnet_usb && !one_card_mode) {                    
4293 +                    pQmapDev->driver_info = rmnet_usb_info;
4294 +                    pQmapDev->driver_info.data = dev->driver_info->data;
4295 +                    dev->driver_info = &pQmapDev->driver_info;
4296 +                }
4297 +
4298 +                if (pQmapDev->use_rmnet_usb && !one_card_mode) {
4299 +                    pQmapDev->usbnet_bh = dev->bh;
4300 +                    tasklet_init(&dev->bh, usbnet_bh, (unsigned long)pQmapDev);
4301 +                }
4302 +            }
4303 +        }
4304 +
4305 +        info->unused = (unsigned long)pQmapDev;
4306 +        dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
4307 +
4308 +        dev_info(&intf->dev, "rx_urb_size = %zd\n", dev->rx_urb_size);
4309 +    }
4310 +#endif
4311 +#endif
4312 +
4313 +    return status;
4314 +}
4315 +
4316 +static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf)
4317 +{
4318 +    struct qmi_wwan_state *info = (void *)&dev->data;
4319 +    struct usb_driver *driver = driver_of(intf);
4320 +    struct usb_interface *other;
4321 +
4322 +    if (dev->udev && dev->udev->state == USB_STATE_CONFIGURED) {
4323 +        usb_control_msg(
4324 +            interface_to_usbdev(intf),
4325 +            usb_sndctrlpipe(interface_to_usbdev(intf), 0),
4326 +            0x22, //USB_CDC_REQ_SET_CONTROL_LINE_STATE
4327 +            0x21, //USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE
4328 +            0, //deactive CDC DTR
4329 +            intf->cur_altsetting->desc.bInterfaceNumber,
4330 +            NULL, 0, 100);
4331 +    }
4332 +
4333 +    if (info->subdriver && info->subdriver->disconnect)
4334 +        info->subdriver->disconnect(info->control);
4335 +
4336 +    /* allow user to unbind using either control or data */
4337 +    if (intf == info->control)
4338 +        other = info->data;
4339 +    else
4340 +        other = info->control;
4341 +
4342 +    /* only if not shared */
4343 +    if (other && intf != other) {
4344 +        usb_set_intfdata(other, NULL);
4345 +        usb_driver_release_interface(driver, other);
4346 +    }
4347 +
4348 +    info->subdriver = NULL;
4349 +    info->data = NULL;
4350 +    info->control = NULL;
4351 +}
4352 +
4353 +/* suspend/resume wrappers calling both usbnet and the cdc-wdm
4354 + * subdriver if present.
4355 + *
4356 + * NOTE: cdc-wdm also supports pre/post_reset, but we cannot provide
4357 + * wrappers for those without adding usbnet reset support first.
4358 + */
4359 +static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message)
4360 +{
4361 +    struct usbnet *dev = usb_get_intfdata(intf);
4362 +    struct qmi_wwan_state *info = (void *)&dev->data;
4363 +    int ret;
4364 +
4365 +    /* Both usbnet_suspend() and subdriver->suspend() MUST return 0
4366 +     * in system sleep context, otherwise, the resume callback has
4367 +     * to recover device from previous suspend failure.
4368 +     */
4369 +    ret = usbnet_suspend(intf, message);
4370 +    if (ret < 0)
4371 +        goto err;
4372 +
4373 +    if (intf == info->control && info->subdriver &&
4374 +        info->subdriver->suspend)
4375 +        ret = info->subdriver->suspend(intf, message);
4376 +    if (ret < 0)
4377 +        usbnet_resume(intf);
4378 +err:
4379 +    return ret;
4380 +}
4381 +
4382 +static int qmi_wwan_resume(struct usb_interface *intf)
4383 +{
4384 +    struct usbnet *dev = usb_get_intfdata(intf);
4385 +    struct qmi_wwan_state *info = (void *)&dev->data;
4386 +    int ret = 0;
4387 +    bool callsub = (intf == info->control && info->subdriver &&
4388 +            info->subdriver->resume);
4389 +
4390 +    if (callsub)
4391 +        ret = info->subdriver->resume(intf);
4392 +    if (ret < 0)
4393 +        goto err;
4394 +    ret = usbnet_resume(intf);
4395 +    if (ret < 0 && callsub)
4396 +        info->subdriver->suspend(intf, PMSG_SUSPEND);
4397 +
4398 +#if defined(QUECTEL_WWAN_QMAP)
4399 +    if (!netif_queue_stopped(dev->net)) {
4400 +        qmap_wake_queue((sQmiWwanQmap *)info->unused);
4401 +    }
4402 +#endif
4403 +
4404 +err:
4405 +    return ret;
4406 +}
4407 +
4408 +static int qmi_wwan_reset_resume(struct usb_interface *intf)
4409 +{
4410 +    dev_info(&intf->dev, "device do not support reset_resume\n");
4411 +    intf->needs_binding = 1;
4412 +    return -EOPNOTSUPP;
4413 +}
4414 +
4415 +static struct sk_buff *rmnet_usb_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
4416 +{
4417 +    //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
4418 +    if (skb->protocol != htons(ETH_P_MAP)) {
4419 +        dev_kfree_skb_any(skb);
4420 +        return NULL;
4421 +    }
4422 +
4423 +    return skb;
4424 +}
4425 +
4426 +static int rmnet_usb_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
4427 +{
4428 +    struct net_device    *net = dev->net;
4429 +    unsigned headroom = skb_headroom(skb);
4430 +
4431 +#if (LINUX_VERSION_CODE < KERNEL_VERSION( 3,3,1 )) //7bdd402706cf26bfef9050dfee3f229b7f33ee4f
4432 +//some customers port to v3.2
4433 +    if (net->type == ARPHRD_ETHER && headroom < ETH_HLEN) {
4434 +        unsigned tailroom = skb_tailroom(skb);
4435 +
4436 +        if ((tailroom + headroom) >= ETH_HLEN) {
4437 +            unsigned moveroom = ETH_HLEN - headroom;
4438 +
4439 +            memmove(skb->data + moveroom ,skb->data, skb->len);
4440 +            skb->data += moveroom;
4441 +            skb->tail += moveroom;
4442 +            #ifdef WARN_ONCE
4443 +            WARN_ONCE(1, "It is better reserve headroom in usbnet.c:rx_submit()!\n");
4444 +            #endif
4445 +        }
4446 +    }
4447 +#endif
4448 +
4449 +    //printk("%s skb=%p, len=%d, protocol=%x, hdr_len=%d\n", __func__, skb, skb->len, skb->protocol, skb->hdr_len);
4450 +    if (net->type == ARPHRD_ETHER && headroom >= ETH_HLEN) {
4451 +        //usbnet.c rx_process() usbnet_skb_return() eth_type_trans()
4452 +        skb_push(skb, ETH_HLEN);
4453 +        skb_reset_mac_header(skb);
4454 +        memcpy(eth_hdr(skb)->h_source, default_modem_addr, ETH_ALEN);
4455 +        memcpy(eth_hdr(skb)->h_dest, net->dev_addr, ETH_ALEN);
4456 +        eth_hdr(skb)->h_proto = htons(ETH_P_MAP);
4457 +
4458 +        return 1;
4459 +    }
4460 +    
4461 +    return 0;
4462 +}
4463 +
4464 +static rx_handler_result_t rmnet_usb_rx_handler(struct sk_buff **pskb)
4465 +{
4466 +    struct sk_buff *skb = *pskb;
4467 +    struct usbnet *dev;
4468 +    struct qmi_wwan_state *info;
4469 +    sQmiWwanQmap *pQmapDev;
4470 +    struct sk_buff *qmap_skb;
4471 +    struct sk_buff_head skb_chain;
4472 +
4473 +    if (!skb)
4474 +        goto done;
4475 +
4476 +    //printk("%s skb=%p, protocol=%x, len=%d\n", __func__, skb, skb->protocol, skb->len);
4477 +
4478 +    if (skb->pkt_type == PACKET_LOOPBACK)
4479 +        return RX_HANDLER_PASS;
4480 +
4481 +    if (skb->protocol != htons(ETH_P_MAP)) {
4482 +        WARN_ON(1);
4483 +        return RX_HANDLER_PASS;
4484 +    }
4485 +    /* when open hyfi function, run cm will make system crash */
4486 +    //dev = rcu_dereference(skb->dev->rx_handler_data);
4487 +    dev = netdev_priv(skb->dev);
4488 +
4489 +    if (dev == NULL) {
4490 +        WARN_ON(1);
4491 +        return RX_HANDLER_PASS;
4492 +    }
4493 +
4494 +    info = (struct qmi_wwan_state *)&dev->data;
4495 +    pQmapDev = (sQmiWwanQmap *)info->unused;
4496 +
4497 +    qmap_packet_decode(pQmapDev, skb, &skb_chain);
4498 +    while ((qmap_skb = __skb_dequeue (&skb_chain))) {
4499 +        struct net_device    *qmap_net = qmap_skb->dev;
4500 +
4501 +        rmnet_vnd_update_rx_stats(qmap_net, 1, qmap_skb->len);
4502 +        if (qmap_net->type == ARPHRD_ETHER)
4503 +            __skb_pull(qmap_skb, ETH_HLEN);
4504 +        netif_receive_skb(qmap_skb);
4505 +    }
4506 +    consume_skb(skb);
4507 +
4508 +done:
4509 +    return RX_HANDLER_CONSUMED;
4510 +}
4511 +
4512 +static const struct driver_info    qmi_wwan_info = {
4513 +    .description    = "WWAN/QMI device",
4514 +    .flags        = FLAG_WWAN,
4515 +    .bind        = qmi_wwan_bind,
4516 +    .unbind        = qmi_wwan_unbind,
4517 +    .manage_power    = qmi_wwan_manage_power,
4518 +};
4519 +
4520 +#define qmi_wwan_raw_ip_info \
4521 +    .description    = "WWAN/QMI device", \
4522 +    .flags        = FLAG_WWAN | FLAG_RX_ASSEMBLE | FLAG_NOARP | FLAG_SEND_ZLP, \
4523 +    .bind        = qmi_wwan_bind, \
4524 +    .unbind        = qmi_wwan_unbind, \
4525 +    .manage_power    = qmi_wwan_manage_power, \
4526 +    .tx_fixup       = qmap_qmi_wwan_tx_fixup, \
4527 +    .rx_fixup       = qmap_qmi_wwan_rx_fixup, \
4528 +
4529 +static const struct driver_info rmnet_usb_info = {
4530 +    .description = "RMNET/USB device",
4531 +    .flags        =  FLAG_WWAN | FLAG_NOARP | FLAG_SEND_ZLP,
4532 +    .bind = qmi_wwan_bind,
4533 +    .unbind = qmi_wwan_unbind,
4534 +    .manage_power = qmi_wwan_manage_power,
4535 +    .tx_fixup = rmnet_usb_tx_fixup,
4536 +    .rx_fixup = rmnet_usb_rx_fixup,
4537 +};
4538 +
4539 +static const struct driver_info qmi_wwan_raw_ip_info_mdm9x07 = {
4540 +    qmi_wwan_raw_ip_info
4541 +    .data = (5<<8)|4, //QMAPV1 and 4KB
4542 +};
4543 +
4544 +// mdm9x40/sdx12/sdx20/sdx24 share the same config
4545 +static const struct driver_info qmi_wwan_raw_ip_info_mdm9x40 = {
4546 +    qmi_wwan_raw_ip_info
4547 +    .data =  (5<<8)|16, //QMAPV1 and 16KB
4548 +};
4549 +
4550 +static const struct driver_info qmi_wwan_raw_ip_info_sdx55 = {
4551 +    qmi_wwan_raw_ip_info
4552 +    .data = (9<<8)|31, //QMAPV5 and 31KB
4553 +};
4554 +
4555 +/* map QMI/wwan function by a fixed interface number */
4556 +#define QMI_FIXED_INTF(vend, prod, num) \
4557 +    USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \
4558 +    .driver_info = (unsigned long)&qmi_wwan_info
4559 +
4560 +#define QMI_FIXED_RAWIP_INTF(vend, prod, num, chip) \
4561 +    USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \
4562 +    .driver_info = (unsigned long)&qmi_wwan_raw_ip_info_##chip
4563 +
4564 +static const struct usb_device_id products[] = {
4565 +    { QMI_FIXED_INTF(0x05C6, 0x9003, 4) },  /* Quectel UC20 */
4566 +    { QMI_FIXED_INTF(0x05C6, 0x9215, 4) },  /* Quectel EC20 (MDM9215) */
4567 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0125, 4, mdm9x07) },  /* Quectel EC20 (MDM9X07)/EC25/EG25 */
4568 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0121, 4, mdm9x07) },  /* Quectel EC21 */
4569 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0191, 4, mdm9x07) },  /* Quectel EG91 */
4570 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0195, 4, mdm9x07) },  /* Quectel EG95 */
4571 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0700, 3, mdm9x07) },  /* Quectel BG95 (at+qcfgext="usbnet","rmnet") */
4572 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0306, 4, mdm9x40) },  /* Quectel EG06/EP06/EM06 */
4573 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x030B, 4, mdm9x40) },  /* Quectel EG065k/EG060K */
4574 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0512, 4, mdm9x40) },  /* Quectel EG12/EP12/EM12/EG16/EG18 */
4575 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0296, 4, mdm9x07) },  /* Quectel BG96 */
4576 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0435, 4, mdm9x07) },  /* Quectel AG35 */
4577 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0620, 4, mdm9x40) },  /* Quectel EG20 */
4578 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0800, 4, sdx55) },  /* Quectel RG500 */
4579 +    { QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0801, 4, sdx55) },  /* Quectel RG520 */
4580 +    { }                    /* END */
4581 +};
4582 +MODULE_DEVICE_TABLE(usb, products);
4583 +
4584 +static int qmi_wwan_probe(struct usb_interface *intf,
4585 +              const struct usb_device_id *prod)
4586 +{
4587 +    struct usb_device_id *id = (struct usb_device_id *)prod;
4588 +
4589 +    /* Workaround to enable dynamic IDs.  This disables usbnet
4590 +     * blacklisting functionality.  Which, if required, can be
4591 +     * reimplemented here by using a magic "blacklist" value
4592 +     * instead of 0 in the static device id table
4593 +     */
4594 +    if (!id->driver_info) {
4595 +        dev_dbg(&intf->dev, "setting defaults for dynamic device id\n");
4596 +        id->driver_info = (unsigned long)&qmi_wwan_info;
4597 +    }
4598 +
4599 +    if (intf->cur_altsetting->desc.bInterfaceClass != 0xff) {
4600 +        dev_info(&intf->dev,  "Quectel module not qmi_wwan mode! please check 'at+qcfg=\"usbnet\"'\n");
4601 +        return -ENODEV;
4602 +    }
4603 +
4604 +    return usbnet_probe(intf, id);
4605 +}
4606 +
4607 +#if defined(QUECTEL_WWAN_QMAP)
4608 +static int qmap_qmi_wwan_probe(struct usb_interface *intf,
4609 +              const struct usb_device_id *prod)
4610 +{
4611 +    int status = qmi_wwan_probe(intf, prod);
4612 +
4613 +    if (!status) {
4614 +        struct usbnet *dev = usb_get_intfdata(intf);
4615 +        struct qmi_wwan_state *info = (void *)&dev->data;
4616 +        sQmiWwanQmap *pQmapDev = (sQmiWwanQmap *)info->unused;
4617 +        unsigned i;
4618 +
4619 +        if (!pQmapDev)
4620 +            return status;
4621 +
4622 +        tasklet_init(&pQmapDev->txq, rmnet_usb_tx_wake_queue, (unsigned long)pQmapDev);
4623 +
4624 +        if (pQmapDev->qmap_mode == 1) {
4625 +            pQmapDev->mpQmapNetDev[0] = dev->net;
4626 +            if (pQmapDev->use_rmnet_usb && !one_card_mode) {
4627 +                pQmapDev->mpQmapNetDev[0] = NULL;
4628 +                qmap_register_device(pQmapDev, 0);
4629 +            }
4630 +        }
4631 +        else if (pQmapDev->qmap_mode > 1) {
4632 +            for (i = 0; i < pQmapDev->qmap_mode; i++) {
4633 +                qmap_register_device(pQmapDev, i);
4634 +            }
4635 +        }
4636 +
4637 +        if (pQmapDev->use_rmnet_usb && !one_card_mode) {
4638 +            rtnl_lock();
4639 +            /* when open hyfi function, run cm will make system crash */
4640 +            //netdev_rx_handler_register(dev->net, rmnet_usb_rx_handler, dev);
4641 +            netdev_rx_handler_register(dev->net, rmnet_usb_rx_handler, NULL);
4642 +            rtnl_unlock();
4643 +        }
4644 +
4645 +        if (pQmapDev->link_state == 0) {
4646 +            netif_carrier_off(dev->net);
4647 +        }
4648 +    }
4649 +
4650 +    return status;
4651 +}
4652 +
4653 +static void qmap_qmi_wwan_disconnect(struct usb_interface *intf)
4654 +{
4655 +    struct usbnet *dev = usb_get_intfdata(intf);
4656 +    struct qmi_wwan_state *info;
4657 +    sQmiWwanQmap *pQmapDev;
4658 +    uint i;
4659 +
4660 +    if (!dev)
4661 +        return;
4662 +
4663 +    info = (void *)&dev->data;
4664 +    pQmapDev = (sQmiWwanQmap *)info->unused;
4665 +
4666 +    if (!pQmapDev) {
4667 +        return usbnet_disconnect(intf);
4668 +    }
4669 +
4670 +    pQmapDev->link_state = 0;
4671 +
4672 +    if (pQmapDev->qmap_mode > 1) {
4673 +        for (i = 0; i < pQmapDev->qmap_mode; i++) {
4674 +            qmap_unregister_device(pQmapDev, i);
4675 +        }
4676 +    }
4677 +
4678 +    if (pQmapDev->use_rmnet_usb && !one_card_mode) {
4679 +        qmap_unregister_device(pQmapDev, 0);
4680 +        rtnl_lock();
4681 +        netdev_rx_handler_unregister(dev->net);
4682 +        rtnl_unlock();
4683 +    }
4684 +
4685 +    tasklet_kill(&pQmapDev->txq);
4686 +    
4687 +    usbnet_disconnect(intf);
4688 +    /* struct usbnet *dev had free by usbnet_disconnect()->free_netdev().
4689 +        so we should access info. */
4690 +    //info->unused = 0;    
4691 +    kfree(pQmapDev);
4692 +}
4693 +#endif
4694 +
4695 +static struct usb_driver qmi_wwan_driver = {
4696 +    .name              = "qmi_wwan_q",
4697 +    .id_table          = products,
4698 +    .probe              = qmi_wwan_probe,
4699 +#if defined(QUECTEL_WWAN_QMAP)
4700 +    .probe              = qmap_qmi_wwan_probe,
4701 +    .disconnect          = qmap_qmi_wwan_disconnect,
4702 +#else
4703 +    .probe              = qmi_wwan_probe,
4704 +    .disconnect          = usbnet_disconnect,
4705 +#endif
4706 +    .suspend          = qmi_wwan_suspend,
4707 +    .resume              =    qmi_wwan_resume,
4708 +    .reset_resume         = qmi_wwan_reset_resume,
4709 +    .supports_autosuspend = 1,
4710 +    .disable_hub_initiated_lpm = 1,
4711 +};
4712 +
4713 +static int __init qmi_wwan_driver_init(void)
4714 +{
4715 +#ifdef CONFIG_QCA_NSS_DRV
4716 +    nss_cb = rcu_dereference(rmnet_nss_callbacks);
4717 +    if (!nss_cb) {
4718 +        printk(KERN_ERR "qmi_wwan_driver_init: driver load must after '/etc/modules.d/42-rmnet-nss'\n");
4719 +    }
4720 +#endif
4721 +    return usb_register(&qmi_wwan_driver);
4722 +}
4723 +module_init(qmi_wwan_driver_init);
4724 +static void __exit qmi_wwan_driver_exit(void)
4725 +{
4726 +    usb_deregister(&qmi_wwan_driver);
4727 +}
4728 +module_exit(qmi_wwan_driver_exit);
4729 +
4730 +MODULE_AUTHOR("Bjørn Mork <bjorn@mork.no>");
4731 +MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver");
4732 +MODULE_LICENSE("GPL");
4733 +MODULE_VERSION(QUECTEL_WWAN_VERSION);
4734 diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
4735 index 691fd8ab7..372241cd5 100644
4736 --- a/drivers/usb/dwc3/core.c
4737 +++ b/drivers/usb/dwc3/core.c
4738 @@ -99,6 +99,9 @@ static int dwc3_get_dr_mode(struct dwc3 *dwc)
4739          dwc->dr_mode = mode;
4740      }
4741  
4742 +    /* Add by linke */
4743 +    dwc->dr_mode = USB_DR_MODE_OTG;
4744 +
4745      return 0;
4746  }
4747  
4748 diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
4749 index 697683e3f..3fe38fb85 100644
4750 --- a/drivers/usb/serial/option.c
4751 +++ b/drivers/usb/serial/option.c
4752 @@ -198,8 +198,6 @@ static void option_instat_callback(struct urb *urb);
4753  
4754  #define DELL_PRODUCT_5821E            0x81d7
4755  #define DELL_PRODUCT_5821E_ESIM            0x81e0
4756 -#define DELL_PRODUCT_5829E_ESIM            0x81e4
4757 -#define DELL_PRODUCT_5829E            0x81e6
4758  
4759  #define KYOCERA_VENDOR_ID            0x0c88
4760  #define KYOCERA_PRODUCT_KPC650            0x17da
4761 @@ -252,14 +250,10 @@ static void option_instat_callback(struct urb *urb);
4762  #define QUECTEL_PRODUCT_EG95            0x0195
4763  #define QUECTEL_PRODUCT_BG96            0x0296
4764  #define QUECTEL_PRODUCT_EP06            0x0306
4765 -#define QUECTEL_PRODUCT_EM05G            0x030a
4766 -#define QUECTEL_PRODUCT_EM060K            0x030b
4767  #define QUECTEL_PRODUCT_EM12            0x0512
4768  #define QUECTEL_PRODUCT_RM500Q            0x0800
4769 -#define QUECTEL_PRODUCT_RM520N            0x0801
4770  #define QUECTEL_PRODUCT_EC200S_CN        0x6002
4771  #define QUECTEL_PRODUCT_EC200T            0x6026
4772 -#define QUECTEL_PRODUCT_RM500K            0x7001
4773  
4774  #define CMOTECH_VENDOR_ID            0x16d8
4775  #define CMOTECH_PRODUCT_6001            0x6001
4776 @@ -436,12 +430,6 @@ static void option_instat_callback(struct urb *urb);
4777  #define CINTERION_PRODUCT_CLS8            0x00b0
4778  #define CINTERION_PRODUCT_MV31_MBIM        0x00b3
4779  #define CINTERION_PRODUCT_MV31_RMNET        0x00b7
4780 -#define CINTERION_PRODUCT_MV31_2_MBIM        0x00b8
4781 -#define CINTERION_PRODUCT_MV31_2_RMNET        0x00b9
4782 -#define CINTERION_PRODUCT_MV32_WA        0x00f1
4783 -#define CINTERION_PRODUCT_MV32_WB        0x00f2
4784 -#define CINTERION_PRODUCT_MV32_WA_RMNET        0x00f3
4785 -#define CINTERION_PRODUCT_MV32_WB_RMNET        0x00f4
4786  
4787  /* Olivetti products */
4788  #define OLIVETTI_VENDOR_ID            0x0b3c
4789 @@ -577,10 +565,6 @@ static void option_instat_callback(struct urb *urb);
4790  #define WETELECOM_PRODUCT_6802            0x6802
4791  #define WETELECOM_PRODUCT_WMD300        0x6803
4792  
4793 -/* OPPO products */
4794 -#define OPPO_VENDOR_ID                0x22d9
4795 -#define OPPO_PRODUCT_R11            0x276c
4796 -
4797  
4798  /* Device flags */
4799  
4800 @@ -601,6 +585,32 @@ static void option_instat_callback(struct urb *urb);
4801  
4802  
4803  static const struct usb_device_id option_ids[] = {
4804 +#if 1 //Added by Quectel
4805 +    { USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
4806 +    { USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
4807 +    { USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20(MDM9215) */
4808 +    { USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC20(MDM9x07)/EC25/EG25 */
4809 +    { USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
4810 +    { USB_DEVICE(0x2C7C, 0x0191) }, /* Quectel EG91 */
4811 +    { USB_DEVICE(0x2C7C, 0x0195) }, /* Quectel EG95 */
4812 +    { USB_DEVICE(0x2C7C, 0x0306) }, /* Quectel EG06/EP06/EM06 */
4813 +    { USB_DEVICE(0x2C7C, 0x030B) }, /* Quectel EG065K/EG060K */
4814 +    { USB_DEVICE(0x2C7C, 0x0514) }, /* Quectel BL EG060K RNDIS Only */
4815 +    { USB_DEVICE(0x2C7C, 0x0512) }, /* Quectel EG12/EP12/EM12/EG16/EG18 */
4816 +    { USB_DEVICE(0x2C7C, 0x0296) }, /* Quectel BG96 */
4817 +    { USB_DEVICE(0x2C7C, 0x0700) }, /* Quectel BG95/BG77/BG600L-M3/BC69 */
4818 +    { USB_DEVICE(0x2C7C, 0x0435) }, /* Quectel AG35 */
4819 +    { USB_DEVICE(0x2C7C, 0x0415) }, /* Quectel AG15 */
4820 +    { USB_DEVICE(0x2C7C, 0x0452) }, /* Quectel AG520 */
4821 +    { USB_DEVICE(0x2C7C, 0x0455) }, /* Quectel AG550 */
4822 +    { USB_DEVICE(0x2C7C, 0x0620) }, /* Quectel EG20 */
4823 +    { USB_DEVICE(0x2C7C, 0x0800) }, /* Quectel RG500/RM500/RG510/RM510 */
4824 +    { USB_DEVICE(0x2C7C, 0x0801) }, /* Quectel RG520/RM520/SG520 */
4825 +    { USB_DEVICE(0x2C7C, 0x6026) }, /* Quectel EC200 */
4826 +    { USB_DEVICE(0x2C7C, 0x6120) }, /* Quectel UC200 */
4827 +    { USB_DEVICE(0x2C7C, 0x6000) }, /* Quectel EC200/UC200 */
4828 +    { .match_flags = USB_DEVICE_ID_MATCH_VENDOR, .idVendor = 0x2C7C }, /* Match All Quectel Modules */
4829 +#endif
4830      { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
4831      { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
4832      { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA_LIGHT) },
4833 @@ -1079,10 +1089,6 @@ static const struct usb_device_id option_ids[] = {
4834        .driver_info = RSVD(0) | RSVD(1) | RSVD(6) },
4835      { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5821E_ESIM),
4836        .driver_info = RSVD(0) | RSVD(1) | RSVD(6) },
4837 -    { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E),
4838 -      .driver_info = RSVD(0) | RSVD(6) },
4839 -    { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5829E_ESIM),
4840 -      .driver_info = RSVD(0) | RSVD(6) },
4841      { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },    /* ADU-E100, ADU-310 */
4842      { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
4843      { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
4844 @@ -1139,35 +1145,22 @@ static const struct usb_device_id option_ids[] = {
4845      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0xff, 0xff),
4846        .driver_info = NUMEP2 },
4847      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EG95, 0xff, 0, 0) },
4848 -    { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0203, 0xff), /* BG95-M3 */
4849 -      .driver_info = ZLP },
4850      { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
4851        .driver_info = RSVD(4) },
4852      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
4853        .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
4854      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
4855 -    { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff),
4856 -      .driver_info = RSVD(6) | ZLP },
4857 -    { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) },
4858 -    { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) },
4859 -    { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) },
4860      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
4861        .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
4862      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
4863      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) },    /* EM160R-GL */
4864      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) },
4865 -    { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, 0x0700, 0xff), /* BG95 */
4866 -      .driver_info = RSVD(3) | ZLP },
4867      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) },
4868      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
4869      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
4870        .driver_info = ZLP },
4871 -    { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) },
4872 -    { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) },
4873 -    { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) },
4874      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) },
4875      { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) },
4876 -    { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) },
4877  
4878      { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
4879      { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
4880 @@ -1244,10 +1237,6 @@ static const struct usb_device_id option_ids[] = {
4881        .driver_info = NCTRL(0) | RSVD(1) },
4882      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1056, 0xff),    /* Telit FD980 */
4883        .driver_info = NCTRL(2) | RSVD(3) },
4884 -    { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1057, 0xff),    /* Telit FN980 */
4885 -      .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
4886 -    { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1058, 0xff),    /* Telit FN980 (PCIe) */
4887 -      .driver_info = NCTRL(0) | RSVD(1) },
4888      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1060, 0xff),    /* Telit LN920 (rmnet) */
4889        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
4890      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1061, 0xff),    /* Telit LN920 (MBIM) */
4891 @@ -1264,8 +1253,6 @@ static const struct usb_device_id option_ids[] = {
4892        .driver_info = NCTRL(2) | RSVD(3) },
4893      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1073, 0xff),    /* Telit FN990 (ECM) */
4894        .driver_info = NCTRL(0) | RSVD(1) },
4895 -    { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1075, 0xff),    /* Telit FN990 (PCIe) */
4896 -      .driver_info = RSVD(0) },
4897      { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910),
4898        .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) },
4899      { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM),
4900 @@ -1300,7 +1287,6 @@ static const struct usb_device_id option_ids[] = {
4901        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
4902      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x1231, 0xff),    /* Telit LE910Cx (RNDIS) */
4903        .driver_info = NCTRL(2) | RSVD(3) },
4904 -    { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x1250, 0xff, 0x00, 0x00) },    /* Telit LE910Cx (rmnet) */
4905      { USB_DEVICE(TELIT_VENDOR_ID, 0x1260),
4906        .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) },
4907      { USB_DEVICE(TELIT_VENDOR_ID, 0x1261),
4908 @@ -1313,16 +1299,10 @@ static const struct usb_device_id option_ids[] = {
4909        .driver_info = NCTRL(2) },
4910      { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x7011, 0xff),    /* Telit LE910-S1 (ECM) */
4911        .driver_info = NCTRL(2) },
4912 -    { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701a, 0xff),    /* Telit LE910R1 (RNDIS) */
4913 -      .driver_info = NCTRL(2) },
4914 -    { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x701b, 0xff),    /* Telit LE910R1 (ECM) */
4915 -      .driver_info = NCTRL(2) },
4916      { USB_DEVICE(TELIT_VENDOR_ID, 0x9010),                /* Telit SBL FN980 flashing device */
4917        .driver_info = NCTRL(0) | ZLP },
4918      { USB_DEVICE(TELIT_VENDOR_ID, 0x9200),                /* Telit LE910S1 flashing device */
4919        .driver_info = NCTRL(0) | ZLP },
4920 -    { USB_DEVICE(TELIT_VENDOR_ID, 0x9201),                /* Telit LE910R1 flashing device */
4921 -      .driver_info = NCTRL(0) | ZLP },
4922      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
4923      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
4924        .driver_info = RSVD(1) },
4925 @@ -1695,8 +1675,6 @@ static const struct usb_device_id option_ids[] = {
4926        .driver_info = RSVD(2) },
4927      { USB_DEVICE_INTERFACE_CLASS(ZTE_VENDOR_ID, 0x1476, 0xff) },    /* GosunCn ZTE WeLink ME3630 (ECM/NCM mode) */
4928      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0x00, 0x00) }, /* ZTE MF871A */
4929 -    { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1485, 0xff, 0xff, 0xff),  /* ZTE MF286D */
4930 -      .driver_info = RSVD(5) },
4931      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) },
4932      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) },
4933      { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) },
4934 @@ -2003,18 +1981,6 @@ static const struct usb_device_id option_ids[] = {
4935        .driver_info = RSVD(3)},
4936      { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_RMNET, 0xff),
4937        .driver_info = RSVD(0)},
4938 -    { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_MBIM, 0xff),
4939 -      .driver_info = RSVD(3)},
4940 -    { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV31_2_RMNET, 0xff),
4941 -      .driver_info = RSVD(0)},
4942 -    { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA, 0xff),
4943 -      .driver_info = RSVD(3)},
4944 -    { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WA_RMNET, 0xff),
4945 -      .driver_info = RSVD(0) },
4946 -    { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB, 0xff),
4947 -      .driver_info = RSVD(3)},
4948 -    { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_MV32_WB_RMNET, 0xff),
4949 -      .driver_info = RSVD(0) },
4950      { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100),
4951        .driver_info = RSVD(4) },
4952      { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120),
4953 @@ -2157,14 +2123,10 @@ static const struct usb_device_id option_ids[] = {
4954        .driver_info = RSVD(3) },
4955      { USB_DEVICE(0x1508, 0x1001),                        /* Fibocom NL668 (IOT version) */
4956        .driver_info = RSVD(4) | RSVD(5) | RSVD(6) },
4957 -    { USB_DEVICE(0x1782, 0x4d10) },                        /* Fibocom L610 (AT mode) */
4958 -    { USB_DEVICE_INTERFACE_CLASS(0x1782, 0x4d11, 0xff) },            /* Fibocom L610 (ECM/RNDIS mode) */
4959      { USB_DEVICE(0x2cb7, 0x0104),                        /* Fibocom NL678 series */
4960        .driver_info = RSVD(4) | RSVD(5) },
4961      { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff),            /* Fibocom NL678 series */
4962        .driver_info = RSVD(6) },
4963 -    { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0106, 0xff) },            /* Fibocom MA510 (ECM mode w/ diag intf.) */
4964 -    { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x010a, 0xff) },            /* Fibocom MA510 (ECM mode) */
4965      { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0xff, 0x30) },    /* Fibocom FG150 Diag */
4966      { USB_DEVICE_AND_INTERFACE_INFO(0x2cb7, 0x010b, 0xff, 0, 0) },        /* Fibocom FG150 AT */
4967      { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) },            /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
4968 @@ -2175,7 +2137,6 @@ static const struct usb_device_id option_ids[] = {
4969      { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) },            /* GosunCn GM500 RNDIS */
4970      { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) },            /* GosunCn GM500 MBIM */
4971      { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) },            /* GosunCn GM500 ECM/NCM */
4972 -    { USB_DEVICE_AND_INTERFACE_INFO(OPPO_VENDOR_ID, OPPO_PRODUCT_R11, 0xff, 0xff, 0x30) },
4973      { } /* Terminating entry */
4974  };
4975  MODULE_DEVICE_TABLE(usb, option_ids);
4976 @@ -2184,7 +2145,26 @@ MODULE_DEVICE_TABLE(usb, option_ids);
4977   * recognizes separately, thus num_port=1.
4978   */
4979  
4980 +#if 1 //Added by Quectel
4981 +static void cfmakeraw(struct ktermios *t)
4982 +{
4983 +    t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
4984 +    t->c_oflag &= ~OPOST;
4985 +    t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
4986 +    t->c_cflag &= ~(CSIZE|PARENB);
4987 +    t->c_cflag |= CS8;
4988 +    t->c_cc[VMIN] = 1;
4989 +    t->c_cc[VTIME] = 0;
4990 +}
4991 +
4992 +static void option_init_termios(struct tty_struct *tty)
4993 +{
4994 +    cfmakeraw(&tty->termios);
4995 +}
4996 +#endif
4997 +
4998  static struct usb_serial_driver option_1port_device = {
4999 +    .init_termios  = option_init_termios,
5000      .driver = {
5001          .owner =    THIS_MODULE,
5002          .name =        "option1",
5003 @@ -2209,6 +2189,9 @@ static struct usb_serial_driver option_1port_device = {
5004  #ifdef CONFIG_PM
5005      .suspend           = usb_wwan_suspend,
5006      .resume            = usb_wwan_resume,
5007 +#if 1 //Added by Quectel
5008 +    .reset_resume = usb_wwan_resume,
5009 +#endif
5010  #endif
5011  };
5012  
5013 @@ -2233,6 +2216,35 @@ static int option_probe(struct usb_serial *serial,
5014                  &serial->interface->cur_altsetting->desc;
5015      unsigned long device_flags = id->driver_info;
5016  
5017 +#if 1 //Added by Quectel
5018 +    //Quectel UC20's interface 4 can be used as USB Network device
5019 +    if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003)
5020 +        && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
5021 +        return -ENODEV;
5022 +
5023 +    //Quectel EC20(MDM9215)'s interface 4 can be used as USB Network device
5024 +    if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215)
5025 +        && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
5026 +        return -ENODEV;
5027 +
5028 +    if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
5029 +        __u16 idProduct = le16_to_cpu(serial->dev->descriptor.idProduct);
5030 +        struct usb_interface_descriptor *intf = &serial->interface->cur_altsetting->desc;
5031 +
5032 +        if (intf->bInterfaceClass != 0xFF || intf->bInterfaceSubClass == 0x42) {
5033 +            //ECM, RNDIS, NCM, MBIM, ACM, UAC, ADB
5034 +            return -ENODEV;
5035 +        }
5036 +
5037 +        if ((idProduct&0xF000) == 0x0000) {
5038 +            //MDM interface 4 is QMI
5039 +            if (intf->bInterfaceNumber == 4 && intf->bNumEndpoints == 3
5040 +                && intf->bInterfaceSubClass == 0xFF && intf->bInterfaceProtocol == 0xFF)
5041 +                return -ENODEV;
5042 +        }
5043 +    }
5044 +#endif
5045 +
5046      /* Never bind to the CD-Rom emulation interface    */
5047      if (iface_desc->bInterfaceClass == USB_CLASS_MASS_STORAGE)
5048          return -ENODEV;
5049 @@ -2346,7 +2358,7 @@ static void option_instat_callback(struct urb *urb)
5050          dev_dbg(dev, "%s: error %d\n", __func__, status);
5051  
5052      /* Resubmit urb so we continue receiving IRQ data */
5053 -    if (status != -ESHUTDOWN && status != -ENOENT) {
5054 +    if (status != -ESHUTDOWN && status != -ENOENT && status != -EPROTO) {
5055          usb_mark_last_busy(port->serial->dev);
5056          err = usb_submit_urb(urb, GFP_ATOMIC);
5057          if (err)
5058 diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
5059 index f21f25a8c..27e642dbd 100644
5060 --- a/drivers/usb/serial/usb_wwan.c
5061 +++ b/drivers/usb/serial/usb_wwan.c
5062 @@ -227,7 +227,7 @@ static void usb_wwan_indat_callback(struct urb *urb)
5063              __func__, status, endpoint);
5064  
5065          /* don't resubmit on fatal errors */
5066 -        if (status == -ESHUTDOWN || status == -ENOENT)
5067 +        if (status == -ESHUTDOWN || status == -ENOENT || status == -EPROTO)
5068              return;
5069      } else {
5070          if (urb->actual_length) {
5071 @@ -389,8 +389,7 @@ void usb_wwan_close(struct usb_serial_port *port)
5072  
5073      /*
5074       * Need to take susp_lock to make sure port is not already being
5075 -     * resumed, but no need to hold it due to the tty-port initialized
5076 -     * flag.
5077 +     * resumed, but no need to hold it due to initialized
5078       */
5079      spin_lock_irq(&intfdata->susp_lock);
5080      if (--intfdata->open_ports == 0)
5081 @@ -432,6 +431,19 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
5082                usb_sndbulkpipe(serial->dev, endpoint) | dir,
5083                buf, len, callback, ctx);
5084  
5085 +#if 1 //Added by Quectel for Zero Packet
5086 +    if (dir == USB_DIR_OUT) {
5087 +        if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9090))
5088 +            urb->transfer_flags |= URB_ZERO_PACKET;
5089 +        if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9003))
5090 +            urb->transfer_flags |= URB_ZERO_PACKET;
5091 +        if (serial->dev->descriptor.idVendor == cpu_to_le16(0x05C6) && serial->dev->descriptor.idProduct == cpu_to_le16(0x9215))
5092 +            urb->transfer_flags |= URB_ZERO_PACKET;
5093 +        if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C))
5094 +            urb->transfer_flags |= URB_ZERO_PACKET;
5095 +    }
5096 +#endif
5097 +
5098      if (intfdata->use_zlp && dir == USB_DIR_OUT)
5099          urb->transfer_flags |= URB_ZERO_PACKET;
5100  
5101 diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
5102 index a8823e317..60479eb03 100644
5103 --- a/drivers/video/backlight/pwm_bl.c
5104 +++ b/drivers/video/backlight/pwm_bl.c
5105 @@ -552,6 +552,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
5106      if (!state.period && (data->pwm_period_ns > 0))
5107          state.period = data->pwm_period_ns;
5108  
5109 +    state.enabled = true;/*add for eable default backlight*/
5110 +
5111      ret = pwm_apply_state(pb->pwm, &state);
5112      if (ret) {
5113          dev_err(&pdev->dev, "failed to apply initial PWM state: %d\n",
5114 diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
5115 index 7e21829f2..d39d9ebf2 100644
5116 --- a/sound/soc/fsl/fsl-asoc-card.c
5117 +++ b/sound/soc/fsl/fsl-asoc-card.c
5118 @@ -27,6 +27,7 @@
5119  #include "../codecs/wm8962.h"
5120  #include "../codecs/wm8960.h"
5121  #include "../codecs/wm8994.h"
5122 +#include "../codecs/nau8822.h"
5123  
5124  #define CS427x_SYSCLK_MCLK 0
5125  
5126 @@ -48,6 +49,7 @@ enum fsl_asoc_card_type {
5127      CARD_WM8524,
5128      CARD_SI476X,
5129      CARD_WM8958,
5130 +    CARD_NAU8822,
5131  };
5132  
5133  /**
5134 @@ -59,6 +61,7 @@ enum fsl_asoc_card_type {
5135   * @pll_id: PLL id for set_pll()
5136   */
5137  struct codec_priv {
5138 +    struct clk    *mclk;    /* add by weihuihong */
5139      unsigned long mclk_freq;
5140      unsigned long free_freq;
5141      u32 mclk_id;
5142 @@ -226,6 +229,8 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
5143  
5144      /* Specific configuration for PLL */
5145      if (codec_priv->pll_id && codec_priv->fll_id) {
5146 +        if (!IS_ERR(codec_priv->mclk))
5147 +            clk_prepare_enable(codec_priv->mclk); /* add by weihuihong for enable mclk for nau8822 */
5148          if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE ||
5149              priv->sample_format == SNDRV_PCM_FORMAT_S20_3LE)
5150              pll_out = priv->sample_rate * 384;
5151 @@ -334,6 +339,7 @@ static int fsl_asoc_card_hw_free(struct snd_pcm_substream *substream)
5152              dev_err(dev, "failed to stop FLL: %d\n", ret);
5153              return ret;
5154          }
5155 +        clk_disable_unprepare(codec_priv->mclk);/* add by weihuihong */
5156      }
5157  
5158      return 0;
5159 @@ -764,6 +770,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
5160          }
5161      }
5162  
5163 +    dev_info(codec_dev, "codec mclk freq is %ld", priv->codec_priv.mclk_freq); /* add by weihuihong */
5164 +
5165      /* Default sample rate and format, will be updated in hw_params() */
5166      priv->sample_rate = 44100;
5167      priv->sample_format = SNDRV_PCM_FORMAT_S16_LE;
5168 @@ -813,6 +821,15 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
5169          priv->codec_priv.pll_id = WM8960_SYSCLK_AUTO;
5170          priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
5171          priv->card_type = CARD_WM8960;
5172 +    } else if (of_device_is_compatible(np, "fsl,imx-audio-nau8822")) { /*  add by weihuihong */
5173 +        codec_dai_name = "nau8822-hifi";
5174 +        priv->codec_priv.mclk_id = NAU8822_CLK_MCLK;
5175 +        priv->codec_priv.fll_id = NAU8822_CLK_PLL;//second clk
5176 +        priv->codec_priv.pll_id = NAU8822_CLK_PLL;
5177 +        priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
5178 +        priv->card_type = CARD_NAU8822;
5179 +        if (codec_dev)
5180 +            priv->codec_priv.mclk = devm_clk_get(codec_dev, NULL);
5181      } else if (of_device_is_compatible(np, "fsl,imx-audio-ac97")) {
5182          codec_dai_name = "ac97-hifi";
5183          priv->dai_fmt = SND_SOC_DAIFMT_AC97;
5184 @@ -1171,6 +1188,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
5185      { .compatible = "fsl,imx-audio-wm8524", },
5186      { .compatible = "fsl,imx-audio-si476x", },
5187      { .compatible = "fsl,imx-audio-wm8958", },
5188 +    { .compatible = "fsl,imx-audio-nau8822", },
5189      {}
5190  };
5191  MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);